【问题标题】:WPF DataGrid - Modifing Visuals out of scroll view at runtimeWPF DataGrid - 在运行时从滚动视图中修改视觉对象
【发布时间】:2016-10-11 22:55:21
【问题描述】:

我有多个 DataGrid,其中第一列有一个复选框,标题也有一个复选框。正如我们所见,我希望能够单击标题复选框并让它选中下面的所有复选框。

   <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;
        }

点击数据网格

    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 的其余部分更改为不可见?

【问题讨论】:

  • DataGridHeader_CheckedDataGridHeader_Unchecked的实现在哪里?
  • 添加相关代码

标签: c# wpf checkbox datagrid


【解决方案1】:

我完全改变了它的工作方式,并在后面的数据中添加了 IsChecked。然后我遍历数据并偶然发现 IsChecked 并刷新了网格

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-27
    • 1970-01-01
    • 1970-01-01
    • 2011-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多