WPF:在单击“全选”复选框控件时选择/取消选择列表视图的数据项

本文关键字:选择 取消 列表 视图 数据项 控件 单击 全选 复选框 WPF | 更新日期: 2023-09-27 18:32:23

我正在开发一个 WPF 应用程序,我必须在GroupBox容器中绑定三个不同的ListViews

这是显示器的 XAML:

<GroupBox Header="Zone2 Sensors" Height="250" Name="grpBoxZone2" Width="380" Margin="25,248,90,660" Grid.Column="5" Grid.ColumnSpan="2" Foreground="#FF1E5EE6">
    <Grid Height="250" Width="375" MinHeight="250">
        <Label Content="Strain" Width="40" Name="labelZone2S" Foreground="#FF1E5EE6" Margin="44,1,291,227" />
        <Label Content="Accelerometer" Width="79" Name="labelZone2A" Foreground="#FF1E5EE6" Margin="132,1,164,227" />
        <Label Content="Tilt" Name="labelZone2T" Foreground="#FF1E5EE6" Margin="264,1,82,227" />
        <ListView Margin="25,42,268,49" Name="lst2" ItemsSource="{Binding}" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" BorderThickness="0" SelectionChanged="lst2_SelectionChanged">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Border Padding="5" Background="#FF83A2DA" BorderThickness="1" BorderBrush="Black">
                        <CheckBox Name="CheckBoxs1" IsChecked="{Binding IsSelected}" Click="CheckBoxs1_Click" Unchecked="CheckBoxs1_Unchecked">
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="{Binding ObjectData}"></TextBlock>
                            </StackPanel>
                        </CheckBox>
                    </Border>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <ListView Margin="134,42,159,111" Name="lstZone2A" ItemsSource="{Binding}" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" BorderThickness="0" SelectionChanged="lstZone2A_SelectionChanged">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Border Padding="5" Background="#FF83A2DA" BorderThickness="1" BorderBrush="Black">
                        <CheckBox Name="ChkZone2A" IsChecked="{Binding IsSelected}" Checked="ChkZone2A_Checked" Unchecked="ChkZone2A_Unchecked">
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="{Binding ObjectData}"></TextBlock>
                            </StackPanel>
                        </CheckBox>
                    </Border>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <ListView Margin="249,42,44,156" Name="lstZone2T" ItemsSource="{Binding}" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" BorderThickness="0" SelectionChanged="lstZone2T_SelectionChanged">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Border Padding="5" Background="#FF83A2DA" BorderThickness="1" BorderBrush="Black">
                        <CheckBox Name="ChkZone2T" IsChecked="{Binding IsSelected}" Checked="ChkZone2T_Checked" Unchecked="ChkZone2T_Unchecked">
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="{Binding ObjectData}"></TextBlock>
                            </StackPanel>
                        </CheckBox>
                    </Border>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <CheckBox Content="Select ALL Sensors" Margin="14,21,248,213" Name="chkZone2SelectAll" Checked="chkZone2SelectAll_Checked" Unchecked="chkZone2SelectAll_Unchecked" />
    </Grid>
</GroupBox>

这是我用来检查和取消检查项的 C# 代码:

private void chkZone2SelectAll_Checked(object sender, RoutedEventArgs e)
{
    try
    {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < lst2.Items.Count; i++)
        {
                // Get a all list items from listbox
                ListBoxItem ListBoxItemObj = (ListBoxItem)lst2.ItemContainerGenerator.ContainerFromItem(lst2.Items[i]);
                //bool check = ListBoxItemObj.HasContent;
                // find a ContentPresenter of that list item.. [Call FindVisualChild Method]
                ContentPresenter ContentPresenterObj = FindVisualChild<ContentPresenter>(ListBoxItemObj);
                // call FindName on the DataTemplate of that ContentPresenter
                DataTemplate DataTemplateObj = ContentPresenterObj.ContentTemplate;
                CheckBox Chk = (CheckBox)DataTemplateObj.FindName("CheckBoxs1", ContentPresenterObj);
                Chk.IsChecked = true;
        }
        for (int i = 0; i < lstZone2A.Items.Count; i++)
        {
            // Get a all list items from listbox
            ListBoxItem ListBoxItemObj = (ListBoxItem)lstZone2A.ItemContainerGenerator.ContainerFromItem(lstZone2A.Items[i]);
            // find a ContentPresenter of that list item.. [Call FindVisualChild Method]
            ContentPresenter ContentPresenterObj = FindVisualChild<ContentPresenter>(ListBoxItemObj);
            // call FindName on the DataTemplate of that ContentPresenter
            DataTemplate DataTemplateObj = ContentPresenterObj.ContentTemplate;
            CheckBox Chk = (CheckBox)DataTemplateObj.FindName("ChkZone2A", ContentPresenterObj);
            Chk.IsChecked = true;
        }
        for (int i = 0; i < lstZone2T.Items.Count; i++)
        {
            // Get a all list items from listbox
            ListBoxItem ListBoxItemObj = (ListBoxItem)lstZone2T.ItemContainerGenerator.ContainerFromItem(lstZone2T.Items[i]);
            // find a ContentPresenter of that list item.. [Call FindVisualChild Method]
            ContentPresenter ContentPresenterObj = FindVisualChild<ContentPresenter>(ListBoxItemObj);
            // call FindName on the DataTemplate of that ContentPresenter
            DataTemplate DataTemplateObj = ContentPresenterObj.ContentTemplate;
            CheckBox Chk = (CheckBox)DataTemplateObj.FindName("ChkZone2T", ContentPresenterObj);
            Chk.IsChecked = true;
        }
        foreach (TripInfo cbObject in lst2.Items)
        {
            cbObject.IsSelected = true;
        }
        foreach (TripInfo cbObject in lstZone2A.Items)
        {
            cbObject.IsSelected = true;
        }
        foreach (TripInfo cbObject in lstZone2T.Items)
        {
            cbObject.IsSelected = true;
        }
        foreach (TripInfo cbObject in lst2.Items)
        {
            if (cbObject.IsSelected)
            {
                if (SelectedSensser != null)
                {
                    if (SelectedSensser.Contains(cbObject.ObjectData.ToString())) { }
                    else
                    {
                        sb.AppendFormat("{0}, ", cbObject.ObjectData.ToString());
                    }
                }
                else
                {
                    sb.AppendFormat("{0}, ", cbObject.ObjectData.ToString());
                }
                SelectedSensser += sb.ToString().Trim();
                sb.Clear();
            }
        }
        foreach (TripInfo cbObject in lstZone2A.Items)
        {
            if (cbObject.IsSelected)
            {
                if (SelectedSensser != null)
                {
                    if (SelectedSensser.Contains(cbObject.ObjectData.ToString())) { }
                    else
                    {
                        sb.AppendFormat("{0}, ", cbObject.ObjectData.ToString());
                    }
                }
                else
                {
                    sb.AppendFormat("{0}, ", cbObject.ObjectData.ToString());
                }
                SelectedSensser += sb.ToString().Trim();
                sb.Clear();
            }
        }
        foreach (TripInfo cbObject in lstZone2T.Items)
        {
            if (cbObject.IsSelected)
            {
                if (SelectedSensser != null)
                {
                    if (SelectedSensser.Contains(cbObject.ObjectData.ToString())) { }
                    else
                    {
                        sb.AppendFormat("{0}, ", cbObject.ObjectData.ToString());
                    }
                }
                else
                {
                    sb.AppendFormat("{0}, ", cbObject.ObjectData.ToString());
                }
                SelectedSensser += sb.ToString().Trim();
                sb.Clear();
            }
        }
    }
    catch (Exception ex) { throw ex; }
}
private ChildControl FindVisualChild<ChildControl>(DependencyObject DependencyObj) where ChildControl : DependencyObject
{
    int count = VisualTreeHelper.GetChildrenCount(DependencyObj);
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(DependencyObj); i++)
    {
        DependencyObject Child = VisualTreeHelper.GetChild(DependencyObj, i);
        if (Child != null && Child is ChildControl)
        {
            return (ChildControl)Child;
        }
        else
        {
            ChildControl ChildOfChild = FindVisualChild<ChildControl>(Child);
            if (ChildOfChild != null)
            {
                return ChildOfChild;
            }
        }
    }
    return null;
}
public class TripInfo
{
public TripInfo(string objectData) { ObjectData = objectData; }
public TripInfo(bool isSelected, string objectData)
{
    IsSelected = isSelected;
    ObjectData = objectData;
}
public Boolean IsSelected
{ get; set; }
public String ObjectData
{ get; set; }
}

但是,当它到达第 8 个索引时,这给了我以下错误,但ListItems计数显示 10 个元素:

Value cannot be null.
Parameter name: element

WPF:在单击“全选”复选框控件时选择/取消选择列表视图的数据项

感谢所有刚刚访问这个问题的人。我找到了解决方案。这是一件棘手的事情:-).垂直滚动下的列表项,或者您可以说 FindVisualChild 类找不到那些不可见的项。当我增加列表视图和找到的所有项目的高度时。

我看到您正在使用绑定和模板来显示您的数据。
您可以轻松地在视图模型上调用ICommand并将所有项目设置为 IsSelected=True 。如果你正确地实现了INotifyPropertyChanged它应该可以工作,你不再需要代码隐藏/FindVisual的东西了。