【问题标题】:Get ListViewItem control in CodeBehind在 CodeBehind 中获取 ListViewItem 控件
【发布时间】:2012-06-06 18:59:37
【问题描述】:

我有一个列表视图,每个 Item 都有一个 CheckBox 控件作为其 ItemTemplate 的一部分。

<ListView x:Name="taskListView" Grid.Row="2" BorderThickness="0" Margin="30,0,0,0" ItemsSource="{Binding ChildItems}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="25"/>
                        <ColumnDefinition Width="290"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                    <CheckBox Grid.Column="0" HorizontalAlignment="Center"></CheckBox>
                    <TextBlock Text="{Binding Name}" MaxWidth="270" Grid.Column="1" Margin="0,0,10,0"/>
                    <ComboBox SelectedItem="{Binding DependentTask, Mode=TwoWay}" 
                              Grid.Column="2"
                              Margin="0,3,0,3"
                              ItemsSource="{Binding DependentTasks, Converter={StaticResource addEmptyItemConverter}}" 
                              HorizontalAlignment="Left"
                              MinWidth="150"
                              DisplayMemberPath="ProjectionTaskLink.Name"/>
                </Grid>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

此 ListView 的父级也有一个复选框。检查该父复选框后,我想检查ListViewItems中的所有复选框。如何在 Codebehind 中获取这些内容,以便根据父条件将它们设置为 Checked 或 Unchecked?

谢谢。

编辑:这是完整的 XAML:

<Grid Margin="0,10,0,0">
    <Grid.RowDefinitions>
        <RowDefinition Height="25"/>
        <RowDefinition Height="20"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Grid Grid.Row="0">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="25"/>
            <ColumnDefinition Width="400"/>
            <ColumnDefinition Width="35"/>
            <ColumnDefinition Width="35"/>
        </Grid.ColumnDefinitions>
        <CheckBox HorizontalAlignment="Center" Grid.Column="0" Checked="CheckBox_Checked"/>
        <TextBlock Text="{Binding Name}" Grid.Column="1"/>
        <TextBlock Text="Loops " Grid.Column="2" TextAlignment="Center"/>
        <TextBox Text="{Binding Scenarios}" Grid.Column="3"/>
    </Grid>
    <TextBlock Visibility="{Binding ContainsProjectionTasks, Converter={StaticResource boolToVisibilityConverter}}" 
                   HorizontalAlignment="Left" 
                   Width="450" 
                   TextAlignment="Right" 
                   VerticalAlignment="Bottom" 
                   Grid.Row="1" 
                   Text="Task Dependencies" 
                   Background="White"/>
    <ListView x:Name="taskListView" Grid.Row="2" BorderThickness="0" Margin="30,0,0,0" ItemsSource="{Binding ChildItems}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="25"/>
                        <ColumnDefinition Width="290"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                    <CheckBox Grid.Column="0" HorizontalAlignment="Center"></CheckBox>
                    <TextBlock Text="{Binding Name}" MaxWidth="270" Grid.Column="1" Margin="0,0,10,0"/>
                    <ComboBox SelectedItem="{Binding DependentTask, Mode=TwoWay}" 
                              Grid.Column="2"
                              Margin="0,3,0,3"
                              ItemsSource="{Binding DependentTasks, Converter={StaticResource addEmptyItemConverter}}" 
                              HorizontalAlignment="Left"
                              MinWidth="150"
                              DisplayMemberPath="ProjectionTaskLink.Name"/>
                </Grid>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Grid>

【问题讨论】:

    标签: c# wpf xaml code-behind


    【解决方案1】:

    让 ChildItems 的元素实现 INotifyPropertyChanged。

    为这些元素添加一个名为 IsChecked 的属性,这会在 setter 中引发 NotifyPropertyChangedEvent。

    将 ListViewItem 的复选框绑定到 IsChecked 属性

    我假设您已经在处理父复选框上的选中事件。因此,您现在需要做的就是将其添加到代码隐藏方法中:

    (foreach YourType item in ChildItems)
        item.IsChecked = parentCheckbox.IsChecked;
    

    或者您可以尝试(其中 parentCheckboxName 是主复选框的 x:Name。

    <CheckBox IsChecked="{Binding Path=IsChecked, ElementName=parentCheckboxName}" Grid.Column="0" HorizontalAlignment="Center" />
    

    【讨论】:

    • 我正在使用 MVVM,所以从技术上讲,我认为我不应该在代码隐藏中引用 ViewModel 项。这就是为什么我只想从 ListViewItems 中获取 Checkboxes 的集合,并将它们设置为选中或未选中。
    • 我的解决方案中的第二个代码 sn-p 应该做你想做的事。
    【解决方案2】:

    在您的列表视图项目源中为列表视图中的复选框创建一个属性,并将其绑定到该属性。

    然后您可以在父复选框的 Checked 和 UnChecked 事件中编写此代码:

    foreach(var item in myItemsSource)
       item.IsChecked=ParentCheckBox.IsChecked.GetValueOrDefault();
    

    祝你好运。

    【讨论】:

      【解决方案3】:

      在标记中绑定这两个复选框:

      <CheckBox IsChecked="{Binding Path=IsChecked, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type YourAncestorType}}}" Grid.Column="0" HorizontalAlignment="Center" />
      

      这里不需要使用代码隐藏。

      【讨论】:

      • 鉴于我上面的编辑现在有完整的 xaml,我的祖先类型是什么?顶部网格中的复选框是我的父母。
      • 但是这个复选框不是ListView的祖先。正如 Malcolm O'Hare 所说,您应该在这里使用ElementName
      • 我想通了。 ElementName 也不起作用。但是,当通过 setter 和 NotifyPropertyChanged 检查父级时,我只是在 ViewModel 中附加 ListView Item 源。
      【解决方案4】:

      我最终只是在我的 ViewModel 中更改了父复选框 IsChecked 属性的设置器中的 ListView ItemsSource 集合。这消除了对代码隐藏的任何需求。再加上 NotifyPropertyChanged,它现在可以工作了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-04-22
        • 1970-01-01
        • 2013-01-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多