WPF:单击全选复选框控件选择/取消选择ListView的数据项

时间:2012-04-25 12:11:20

标签: c# wpf

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

这是显示的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

2 个答案:

答案 0 :(得分:0)

感谢所有刚访问此问题的人。我找到了解决方案。这有点棘手 :-)。列在垂直滚动下的列表项,或者你可以说FindVisualChild类找不到那些不可见的项目。当我增加listview的高度和找到的所有项目时。

答案 1 :(得分:0)

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