我有以下数据网格:
<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,但收效甚微。什么是最好的方法来解决这个问题?
答案 0 :(得分:1)
我最近做了类似的功能。最好的方法是创建一个行为:
在网格上方添加复选框(全选)
SelectionMode
属性应为&#34; 扩展&#34;
创建行为
将复选框和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();
}
}
}));
}
和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>
我相信它应该正是你所需要的。