问题描述
我正在使用 WPF 数据网格,并且具有 SelectionUnit="Cell" 和 SelectionMode="Extended".我也在尽可能地遵守 MVVM 原则.
I'm using the WPF datagrid, and have SelectionUnit="Cell" and SelectionMode="Extended". I'm also trying to adhere to the MVVM principals as much as I can.
我需要我的 ViewModel 来跟踪当前的 SelectedCells.
I need my ViewModel to keep track of the current SelectedCells.
如果我可以将它的 SelectedCells 属性绑定到我的 ViewModel,生活就会很简单.奇怪的是,SelectedCells 只引发一次 - 当我们第一次选择网格中的任何单元格时.
Life would be easy if I could just Bind its SelectedCells property to my ViewModel. Oddly enough, SelectedCells is only raised once - when we first select any cell in the grid.
MS 在这里解释:http://social.msdn.microsoft.com/Forums/en/wpf/thread/737117f4-6d20-4232-88cf-e52cc44d4431
谁能想到一种对 MVVM 友好的方法来解决它?
Can anyone think of an MVVM-friendly approach to get around it?
谢谢!
推荐答案
我意识到我的最后一个答案是针对 SelectedItems 而不是 SelectedCells,因此我编写了一个完整的附加属性类来为多个 SelectedCells 进行数据绑定,其工作方式如下:
I realized my last answer was for SelectedItems instead of SelectedCells, so I wrote a complete attached property class to do data binding for multiple SelectedCells which works as follows:
<controls:DataGrid ItemsSource="{StaticResource list}"
SelectionMode="Extended"
behaviors:DataGridSelectedCellsBehavior.SelectedCells="{Binding Path=SelectedGridCellCollection, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
我有一个可用的源代码和一个演示项目这里.
I have a working source code and a demo project of it here.
附加属性行为代码:
public class DataGridSelectedCellsBehavior
{
// Source : https://archive.codeplex.com/?p=datagridthemesfromsl
// Credit to : T. Webster, https://stackoverflow.com/users/266457/t-webster
public static IList<DataGridCellInfo> GetSelectedCells(DependencyObject obj)
{
return (IList<DataGridCellInfo>)obj.GetValue(SelectedCellsProperty);
}
public static void SetSelectedCells(DependencyObject obj, IList<DataGridCellInfo> value)
{
obj.SetValue(SelectedCellsProperty, value);
}
public static readonly DependencyProperty SelectedCellsProperty = DependencyProperty.RegisterAttached("SelectedCells", typeof(IList<DataGridCellInfo>), typeof(DataGridSelectedCellsBehavior), new UIPropertyMetadata(null, OnSelectedCellsChanged));
static SelectedCellsChangedEventHandler GetSelectionChangedHandler(DependencyObject obj)
{
return (SelectedCellsChangedEventHandler)obj.GetValue(SelectionChangedHandlerProperty);
}
static void SetSelectionChangedHandler(DependencyObject obj, SelectedCellsChangedEventHandler value)
{
obj.SetValue(SelectionChangedHandlerProperty, value);
}
static readonly DependencyProperty SelectionChangedHandlerProperty = DependencyProperty.RegisterAttached("SelectedCellsChangedEventHandler", typeof(SelectedCellsChangedEventHandler), typeof(DataGridSelectedCellsBehavior), new UIPropertyMetadata(null));
//d is MultiSelector (d as ListBox not supported)
static void OnSelectedCellsChanged(DependencyObject d, DependencyPropertyChangedEventArgs args)
{
if (GetSelectionChangedHandler(d) != null)
return;
if (d is DataGrid)//DataGrid
{
DataGrid datagrid = d as DataGrid;
SelectedCellsChangedEventHandler selectionchanged = null;
foreach (var selected in GetSelectedCells(d) as IList<DataGridCellInfo>)
datagrid.SelectedCells.Add(selected);
selectionchanged = (sender, e) =>
{
SetSelectedCells(d, datagrid.SelectedCells);
};
SetSelectionChangedHandler(d, selectionchanged);
datagrid.SelectedCellsChanged += GetSelectionChangedHandler(d);
}
//else if (d is ListBox)
//{
// ListBox listbox = d as ListBox;
// SelectionChangedEventHandler selectionchanged = null;
// selectionchanged = (sender, e) =>
// {
// SetSelectedCells(d, listbox.SelectedCells);
// };
// SetSelectionChangedHandler(d, selectionchanged);
// listbox.SelectionChanged += GetSelectionChangedHandler(d);
//}
}
}
查看型号代码:
class DemoViewModel : INotifyPropertyChanged
{
private IList<DataGridCellInfo> selectedGridCellCollection = new List<DataGridCellInfo>();
public IList<DataGridCellInfo> SelectedGridCellCollection
{
get { return selectedGridCellCollection; }
set
{
selectedGridCellCollection = value;
NotifyPropertyChanged();
}
}
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
这篇关于WPF Datagrid:将 SelectedCells 绑定到我的 ViewModel 的 MVVM 友好方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!