WPF DataGrid - 在运行时修改滚动视图中的Visual

时间:2016-06-10 21:15:07

标签: c# wpf checkbox datagrid

我有多个DataGrids,第一列有一个Checkbox,而Header也有一个Checkbox。正如我们所看到的,我希望能够点击标题复选框并选中下面的所有复选框。

   <DataGrid x:Name="dgReportTypes_New" Margin="10,140,0,0" Height="175" VerticalAlignment="Top" HorizontalAlignment="Left" Width="216" AutoGenerateColumns="False" SelectionMode="Single" CanUserAddRows="False" MouseUp="DataGrid_MouseUp" KeyDown="DataGrid_KeyDown">
        <DataGrid.Columns>
            <DataGridCheckBoxColumn IsReadOnly="True"   Binding="{Binding IsChecked, UpdateSourceTrigger=PropertyChanged}" ClipboardContentBinding="{x:Null}">
                <DataGridCheckBoxColumn.HeaderTemplate >
                    <DataTemplate>
                        <CheckBox x:Name="chkSelectAll" IsThreeState="True" Checked="DataGridHeader_Checked" Unchecked="DataGridHeader_Unchecked" Indeterminate="DataGridHeader_Indeterminate"  />
                    </DataTemplate>
                </DataGridCheckBoxColumn.HeaderTemplate>
            </DataGridCheckBoxColumn>
            <DataGridTextColumn IsReadOnly="True"  Binding="{Binding Description}" CanUserResize="False" Width="*"  />
        </DataGrid.Columns>
    </DataGrid>

经过

    private void DataGridHeader_Checked(object sender, RoutedEventArgs e)
    {
        DataGrid dg = SGT.Helpers.ControlHelpers.Generics.FindVisualParent<DataGrid>(sender as DependencyObject, typeof(DataGrid));
        for (int i = 0; i < dg.Items.Count; i++)
        {
            DataGridRow row = (DataGridRow)dg.ItemContainerGenerator.ContainerFromIndex(i);
            CheckBox c = ControlHelpers.CheckBoxes.ToggleCheckBox(row, true);
        }
        e.Handled = true;
    }

未检查

    private void DataGridHeader_Unchecked(object sender, RoutedEventArgs e)
    {
        DataGrid dg = SGT.Helpers.ControlHelpers.Generics.FindVisualParent<DataGrid>(sender as DependencyObject, typeof(DataGrid));
        for (int i = 0; i < dg.Items.Count; i++)
        {
            DataGridRow row = (DataGridRow)dg.ItemContainerGenerator.ContainerFromIndex(i);
            CheckBox c = ControlHelpers.CheckBoxes.ToggleCheckBox(row, false);
        }
        e.Handled = true;
    }

不确定

    private void DataGridHeader_Indeterminate(object sender, RoutedEventArgs e)
    {
        ((CheckBox)sender).IsChecked = false;
        e.Handled = true;
    }

切换

        public static CheckBox ToggleCheckBox(DataGridRow row, bool? overrideValue)
        {
            if (row == null)
            {
                return null;
            }
            CheckBox c = Generics.FindVisualChild<CheckBox>(row as DependencyObject, typeof(CheckBox));

            if (overrideValue != null)
            {
                c.IsChecked = overrideValue;
            }
            else
            {
                c.IsChecked = !c.IsChecked;
            }

            return c;
        }

        public static CheckBox ToggleCheckBox(object sender, MouseButtonEventArgs e, bool? overrideValue)
        {
            DataGridRow row = ItemsControl.ContainerFromElement((DataGrid)sender, e.OriginalSource as DependencyObject) as DataGridRow;
            if (row == null)
            {
                return null;
            }
            CheckBox c = Generics.FindVisualChild<CheckBox>(row as DependencyObject, typeof(CheckBox));

            if (overrideValue != null)
            {
                c.IsChecked = overrideValue;
            }
            else
            {
                c.IsChecked = !c.IsChecked;
            }

            e.Handled = true;
            return c;
        }

查找视觉

        public static T FindVisualChild<T>(DependencyObject parent, Type type) where T : DependencyObject
        {
            if (parent == null)
                Debug.Print("Parent Null");

            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
            {
                var child = VisualTreeHelper.GetChild(parent, i);
                if (child.GetType() == type)
                {
                    Debug.Print(child.ToString());
                    return child as T;
                }
                else
                {
                    T result = FindVisualChild<T>(child, type);
                    if (result != null)
                        return result;
                }
            }
            return null;
        }

DataGrid点击

    private void DataGrid_MouseUp(object sender, MouseButtonEventArgs e)
    {
        CheckBox c = ControlHelpers.CheckBoxes.ToggleCheckBox(sender, e, null);
        ValidateCheckAll((DataGrid)sender);
    }

检查/取消选中项目时处理标题复选框

    private void ValidateCheckAll(DataGrid grid)
    {
        //HeaderedContentControl
        DataGridColumnHeadersPresenter hp = Helpers.ControlHelpers.Generics.FindVisualChild<DataGridColumnHeadersPresenter>(grid, typeof(DataGridColumnHeadersPresenter));
        CheckBox c = Helpers.ControlHelpers.Generics.FindVisualChild<CheckBox>(hp, typeof(CheckBox));

        c.Checked -= new RoutedEventHandler(DataGridHeader_Checked);
        c.Unchecked -= new RoutedEventHandler(DataGridHeader_Unchecked);
        c.Indeterminate -= new RoutedEventHandler(DataGridHeader_Indeterminate);

        int counter = 0;

        for (int i = 0; i < grid.Items.Count; i++)
        {
            DataGridRow row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(i);
            //row.Item
            if (row != null)
            {
                CheckBox ch = Helpers.ControlHelpers.Generics.FindVisualChild<CheckBox>(row, typeof(CheckBox));
                if (ch.IsChecked == true)
                {
                    counter++;
                }
            }
            Debug.Print(counter.ToString() + " of " + grid.Items.Count.ToString());
        }


        if (counter == 0)
        {
            c.IsChecked = false;
        }
        else if (counter == grid.Items.Count)
        {
            c.IsChecked = true;
        }
        else
        {
            c.IsChecked = null;
        }

        c.Checked += new RoutedEventHandler(DataGridHeader_Checked);
        c.Unchecked += new RoutedEventHandler(DataGridHeader_Unchecked);
        c.Indeterminate += new RoutedEventHandler(DataGridHeader_Indeterminate);

    }

我已经按照预期的方式工作,直到...我得到了一个具有可滚动数据的DataGrid。

问题:只有可见的CheckBox会发生变化。我使用视觉效果来获取Checkbox并稍微理解为什么会这样。

问题:有没有办法将其余的CheckBox更改为视图?

1 个答案:

答案 0 :(得分:0)

我完全改变了它的工作方式,并为后面的数据添加了一个IsChecked。然后我循环浏览数据并偶然发现了IsChecked并刷新了网格