Raj*_*eja 5 wpf mvvm wpf-controls wpfdatagrid wpf-4.0
我正在尝试使用MVVM在WPF 4.0中创建一个DataGrid ...
所需功能 -
像这样的东西 -

已经2天了,我无法弄清楚如何有效地解决问题.
一个工作的例子就是我现在所需要的......
如果有人有一个可行的解决方案与我分享,我将非常感激...
N请不要告诉我google这个东西,因为没有一件事对我有用......
更新 -
首先,"选择所有"功能,即选中复选框上的所有复选框,单击列标题中存在的复选框...(我可以选择和取消选择数据网格但不能勾选/取消勾选复选框)
其次,鼠标点击多次选择而不按住Ctrl键..
Rac*_*hel 19
当您使用MVVM时,您必须了解什么是数据以及什么是严格的UI.
您SelectedItems将成为数据的一部分,还是仅仅是您的UI?
如果它是数据的一部分,那么IsSelected你的数据模型上应该有一个属性,即使这意味着扩展数据类以包含IsSelected属性,或创建仅包含bool IsSelected和的包装类object MyDataItem.第一个选项可能是首选,因为您可以保留AutoGenerateColumns="True",并且它使列绑定更简单.
然后,您只需将您绑定DataGridRow.SelectedItem到IsSelected数据项的属性:
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="IsSelected" Value="{Binding IsSelected}" />
</Style>
Run Code Online (Sandbox Code Playgroud)
但是,如果您SelectedItems只是用于UI,或者您在此实例中由于某种原因打破MVVM模式,那么您可以创建未绑定CheckBox并使用一些代码来确保CheckBox正确同步到SelectedItem.
我做了一个快速的示例应用程序,这是我的代码看起来像:
首先,我刚刚CheckBox使用a 将未绑定列添加到列列表中DataGridTemplateColumn.这将在AutoGenerateColumns列列表之前添加.
<DataGrid x:Name="TestDataGrid" ItemsSource="{Binding Test}"
SelectionMode="Extended" CanUserAddRows="False"
PreviewMouseLeftButtonDown="TestDataGrid_PreviewMouseLeftButtonDown_1">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox x:Name="TestCheckBox"
PreviewMouseLeftButtonDown="CheckBox_PreviewMouseLeftButtonDown" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
Run Code Online (Sandbox Code Playgroud)
其次,我添加了一个PreviewMouseDown事件,CheckBox使其设置IsSelected行的属性.
private void CheckBox_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var chk = (CheckBox)sender;
var row = VisualTreeHelpers.FindAncestor<DataGridRow>(chk);
var newValue = !chk.IsChecked.GetValueOrDefault();
row.IsSelected = newValue;
chk.IsChecked = newValue;
// Mark event as handled so that the default
// DataGridPreviewMouseDown doesn't handle the event
e.Handled = true;
}
Run Code Online (Sandbox Code Playgroud)
它需要导航VisualTree以找到DataGridRow与单击相关联的CheckBox选择它,并使生活更轻松我使用我在博客上的一些自定义VisualTreeHelpers来查找DataGridRow.您可以使用相同的代码,也可以创建自己的搜索方法VisualTree.
最后,如果用户点击了除此之外的任何地方CheckBox,我们想要禁用默认DataGrid选择事件.这样可以确保IsSelected只有在单击时才会更改该值CheckBox.
有多种方法可以在不同级别禁用选择,但为了简化生活我只是禁用了DataGrid.PreviewMouseLeftButtonDown事件,如果用户没有点击CheckBox.
private void TestDataGrid_PreviewMouseLeftButtonDown_1(object sender, MouseButtonEventArgs e)
{
var chk = VisualTreeHelpers.FindAncestor<CheckBox>((DependencyObject)e.OriginalSource, "TestCheckBox");
if (chk == null)
e.Handled = true;
}
Run Code Online (Sandbox Code Playgroud)
我再次使用我的自定义VisualTreeHelpers导航可视化树,并查看是否单击了CheckBox,如果用户点击了除此之外的任何位置,则取消该事件CheckBox.
至于加入的你的第二请求CheckBox到SelectAll或UnselectAll项目,这将再次成为依赖,如果你的选择是UI或数据的一部分.
如果它的用户界面的一部分,只需添加一个CheckBox到DataGridTemplateColumn.HeaderTemplate,并单击时,遍历DataGrid.Rows,找到CheckBox在第一列,并选中或取消选中它.
如果它是数据的一部分你仍然可以做同样的事情(只设置绑定值DataGrid.Items而不是CheckBox.IsChecked来自DataGrid.Rows),或者你可以像Adolfo Perez建议的那样,并将它绑定到一个属性上ViewModel.