检查未绑定数据网格的所有列?

时间:2016-11-21 06:12:21

标签: c# wpf datagrid

我有以下数据网格:

enter image description here

<DataGrid x:Name="DataGridOrderItems" Margin="4,10,0,-16"
VerticalGridLinesBrush="LightGray"  HorizontalGridLinesBrush="LightGray" AlternatingRowBackground="Beige"  AlternationCount="2" 
SelectionMode="Single" SelectionUnit="FullRow" 
AutoGenerateColumns="False" IsReadOnly="False" SelectionChanged="dataGridOrderItems_SelectionChanged" FrozenColumnCount ="1">
    <DataGrid.Columns>
        <DataGridTemplateColumn Header="Select" CellTemplate="{StaticResource Template}"/>
        <DataGridTextColumn Header="Resource Id" Binding="{Binding ResourceId}" IsReadOnly="True"/>
        <DataGridTextColumn Header="Resource Name" Binding="{Binding DisplayTitle}" IsReadOnly="True"/>
        <DataGridTextColumn Header="Quantity" Binding="{Binding Quantity}" />
        <DataGridTextColumn Header="Type" Binding="{Binding ResourceType}" IsReadOnly="True"/>
        <DataGridTextColumn Header="Order Date" Binding="{Binding OrderDate, StringFormat=\{0:d\}}" IsReadOnly="True" />
        <DataGridTextColumn Header="Status" Binding="{Binding Status}" IsReadOnly="True"/>
    </DataGrid.Columns>
    <DataGrid.ContextMenu>
        <ContextMenu >
            <MenuItem Header="Select All" Click="SelectAllDatagridOrderItems"  />
        </ContextMenu>
    </DataGrid.ContextMenu>
</DataGrid>


<Window.Resources>
    <DataTemplate x:Key="Template">
        <CheckBox IsChecked="{Binding IsChecked, UpdateSourceTrigger=PropertyChanged}" />
    </DataTemplate>
</Window.Resources>

不幸的是,网格不是数据绑定,我正在尝试创建一个菜单项来选择网格中的所有项目( 设置第一列的值以检查所有内容而不仅仅是选择行本身 )。

我有点困惑如何去做。我试图将它绑定到上下文,然后将其重置为itemsource,但收效甚微。什么是最好的方法来解决这个问题?

3 个答案:

答案 0 :(得分:1)

我最近做了类似的功能。最好的方法是创建一个行为:

  1. 在网格上方添加复选框(全选)

  2. SelectionMode属性应为&#34; 扩展&#34;

  3. 创建行为

  4. 将复选框和datagrid绑定到此行为:

    公共类行为 {

    public static bool? GetSelectAll(DependencyObject obj)
    {
        return (bool?)obj.GetValue(SelectAllProperty);
    }
    
    public static void SetSelectAll(DependencyObject obj, bool? value)
    {
        obj.SetValue(SelectAllProperty, value);
    }
    
    // Using a DependencyProperty as the backing store for SelectAll.  This enables animation, styling, binding, etc...
      public static readonly DependencyProperty SelectAllProperty =
        DependencyProperty.RegisterAttached("SelectAll", typeof(bool?), typeof(Behaviour), new PropertyMetadata(null,
            (o, e) =>
            {
    
                DataGrid dg = o as DataGrid;
                if (dg != null)
                {
                    bool selctAll = Convert.ToBoolean(e.NewValue);
                    if (selctAll)
                    {
                        dg.SelectAll();
                    }
                    else
                    {
                        dg.UnselectAll();
                    }
                }
    
            }));
    

    }

  5. 和XAML:

    <StackPanel>
        <CheckBox x:Name="CheckBox"></CheckBox>
        <DataGrid local:Behaviour.SelectAll="{Binding IsChecked, ElementName=CheckBox}"></DataGrid>
    </StackPanel>
    

    我希望它有所帮助。 我已经运行了这个解决方案并且运行正常。

答案 1 :(得分:1)

您可以将RowHeaderTemplate用于CheckBox,而不是使用DataGridTemplateColumn。然后将CheckBox的IsChecked属性绑定到DataGridRow的IsSelected属性。这样,无论何时选择一行,都会选中复选框,反之亦然。

<DataGrid x:Name="DataGridOrderItems" PreviewMouseLeftButtonDown="dataGridOrderItems_PreviewMouseLeftButtonDown" SelectionMode="Extended" SelectionUnit="FullRow" ...>
    <DataGrid.Columns>
        <DataGridTextColumn Header="Resource Id" Binding="{Binding ResourceId}" IsReadOnly="True"/>
        <DataGridTextColumn Header="Resource Name" Binding="{Binding DisplayTitle}" IsReadOnly="True"/>
        <DataGridTextColumn Header="Quantity" Binding="{Binding Quantity}" />
        <DataGridTextColumn Header="Type" Binding="{Binding ResourceType}" IsReadOnly="True"/>
        <DataGridTextColumn Header="Order Date" Binding="{Binding OrderDate, StringFormat=\{0:d\}}" IsReadOnly="True" />
        <DataGridTextColumn Header="Status" Binding="{Binding Status}" IsReadOnly="True"/>
    </DataGrid.Columns>
    <DataGrid.ContextMenu>
        <ContextMenu >
            <MenuItem Header="Select All" Click="SelectAllDatagridOrderItems"  />
        </ContextMenu>
    </DataGrid.ContextMenu>

    <DataGrid.RowHeaderTemplate>
        <DataTemplate>
            <CheckBox IsChecked="{Binding Path=IsSelected, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridRow}}}"/>
        </DataTemplate>
    </DataGrid.RowHeaderTemplate>
</DataGrid>

因此,选择DataGrid中的所有行也会检查所有复选框:

private void SelectAllDatagridOrderItems(object sender, RoutedEventArgs e)
{
    DataGridOrderItems.SelectAll();
}

另外,为了选择多行,SelectionMode应为Extended

使用户更容易选择多行的一种方法是处理DataGrid的PreviewMouseLeftButtonDown事件。然后,使用VisualTreeHelper查找DataGridRow并选择/取消选择它。

private void dataGridOrderItems_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    DependencyObject depObj = (DependencyObject)e.OriginalSource;

    while (depObj != null && !(depObj is DataGridRow))
    {
        depObj = VisualTreeHelper.GetParent(depObj);
    }

    if (depObj != null && depObj is DataGridRow)
    {
        DataGridRow dgRow = (DataGridRow)depObj;
        dgRow.IsSelected = !dgRow.IsSelected;
        e.Handled = true;
    }
}

有了这个,用户可以选择多行而无需按住Ctrl键。 CheckBox检查系统仍然有效。

答案 2 :(得分:0)

行。我觉得便士最后会掉线!

我对XAML进行了调整,但行为仍然相同。 新XAML:

<DataGrid local:Behaviour.SelectAll="False"
              AutoGenerateColumns="False"
              x:Name="DataGrid"
              ItemsSource="{Binding Items}"
              HorizontalGridLinesBrush="LightGray"
              AlternatingRowBackground="Beige"
              AlternationCount="2"
              SelectionMode="Extended"
              SelectionUnit="FullRow">
        <DataGrid.Columns>
            <DataGridTemplateColumn Header="Select">
                <DataGridTemplateColumn.HeaderTemplate>
                    <DataTemplate>
                        <CheckBox  IsChecked="{Binding Path=(local:Behaviour.SelectAll),RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGrid}}}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.HeaderTemplate>
            </DataGridTemplateColumn>
            <DataGridTextColumn Header="Item"
                                Binding="{Binding Item}"
                                IsReadOnly="True" />

        </DataGrid.Columns>
    </DataGrid>

enter image description here enter image description here

我相信它应该正是你所需要的。