我正在使用 WPF 数据网格,并且具有 SelectionUnit="Cell"和 SelectionMode="Extended"。我也在尽可能地遵守 MVVM 原则。

我需要ViewModel来跟踪当前的SelectedCells。

如果我可以将它的 SelectedCells 属性绑定(bind)到我的 ViewModel,生活就会很简单。奇怪的是, SelectedCells 只引发一次 - 当我们第一次选择网格中的任何单元格时。

MS 在这里解释:http://social.msdn.microsoft.com/Forums/en/wpf/thread/737117f4-6d20-4232-88cf-e52cc44d4431

谁能想到一种对 MVVM 友好的方法来解决它?

谢谢!

最佳答案

我意识到我的最后一个答案是 SelectedItems 而不是 SelectedCells,所以我编写了一个完整的附加属性类来为多个 SelectedCells 进行数据绑定(bind),其工作方式如下:

 <controls:DataGrid ItemsSource="{StaticResource list}"
                      SelectionMode="Extended"
                      behaviors:DataGridSelectedCellsBehavior.SelectedCells="{Binding Path=SelectedGridCellCollection, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

我有一个工作源代码和一个演示项目 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;
}

10-08 14:07