WPF Toolkit DataGrid Multi-Select:如何获取SelectedItems?

Sha*_*que 9 wpf datagrid mvvm wpftoolkit

我正在使用WPF Toolkit的DataGrid.我在DataGrid上启用了属性以允许多行选择行.如何获取SelectedItems?我正在使用MVVM框架将我的ViewModel绑定到我的View.

谢谢!

sam*_*ric 7

以Bill的答案为基础,合并选项1和2,添加一些附加属性作为编写代码隐藏的替代方法,我提出了一个行为.

首先,我们有这样的行为:

Public Class SelectedItemsBehavior

    Public Shared ReadOnly SelectedItemsChangedHandlerProperty As DependencyProperty =
        DependencyProperty.RegisterAttached("SelectedItemsChangedHandler",
            GetType(mvvm.RelayCommand), GetType(SelectedItemsBehavior),
            New FrameworkPropertyMetadata(New PropertyChangedCallback(AddressOf OnSelectedItemsChangedHandlerChanged)))




    Public Shared Function GetSelectedItemsChangedHandler(ByVal element As DependencyObject) As mvvm.RelayCommand
        If element Is Nothing Then Throw New ArgumentNullException("element")
        Return element.GetValue(SelectedItemsChangedHandlerProperty)
    End Function

    Public Shared Sub SetSelectedItemsChangedHandler(ByVal element As DependencyObject, ByVal value As mvvm.RelayCommand)
        If element Is Nothing Then Throw New ArgumentNullException("element")
        element.SetValue(SelectedItemsChangedHandlerProperty, value)
    End Sub

    Private Shared Sub OnSelectedItemsChangedHandlerChanged(d As DependencyObject,
                                                            e As DependencyPropertyChangedEventArgs)

        Dim dataGrid As DataGrid = DirectCast(d, DataGrid)

        If e.OldValue Is Nothing AndAlso e.NewValue IsNot Nothing Then
            AddHandler dataGrid.SelectionChanged, AddressOf ItemsControl_SelectionChanged
        End If

        If e.OldValue IsNot Nothing AndAlso e.NewValue Is Nothing Then
            RemoveHandler dataGrid.SelectionChanged, AddressOf ItemsControl_SelectionChanged
        End If

    End Sub


    Public Shared Sub ItemsControl_SelectionChanged(sender As Object,
                                                    e As SelectionChangedEventArgs)

        Dim dataGrid As DataGrid = DirectCast(sender, DataGrid)

        Dim itemsChangedHandler As RelayCommand = GetSelectedItemsChangedHandler(dataGrid)

        itemsChangedHandler.Execute(dataGrid.SelectedItems)

    End Sub

End Class
Run Code Online (Sandbox Code Playgroud)

C#:

using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
public class SelectedItemsBehavior
{


    public static readonly DependencyProperty SelectedItemsChangedHandlerProperty = DependencyProperty.RegisterAttached("SelectedItemsChangedHandler", typeof(mvvm.RelayCommand), typeof(SelectedItemsBehavior), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnSelectedItemsChangedHandlerChanged)));



    public static mvvm.RelayCommand GetSelectedItemsChangedHandler(DependencyObject element)
    {
        if (element == null)
            throw new ArgumentNullException("element");
        return element.GetValue(SelectedItemsChangedHandlerProperty);
    }

    public static void SetSelectedItemsChangedHandler(DependencyObject element, mvvm.RelayCommand value)
    {
        if (element == null)
            throw new ArgumentNullException("element");
        element.SetValue(SelectedItemsChangedHandlerProperty, value);
    }


    private static void OnSelectedItemsChangedHandlerChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        DataGrid dataGrid = (DataGrid)d;

        if (e.OldValue == null && e.NewValue != null) {
            dataGrid.SelectionChanged += ItemsControl_SelectionChanged;
        }

        if (e.OldValue != null && e.NewValue == null) {
            dataGrid.SelectionChanged -= ItemsControl_SelectionChanged;
        }

    }



    public static void ItemsControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        DataGrid dataGrid = (DataGrid)sender;

        RelayCommand itemsChangedHandler = GetSelectedItemsChangedHandler(dataGrid);

        itemsChangedHandler.Execute(dataGrid.SelectedItems);

    }

}
Run Code Online (Sandbox Code Playgroud)

然后我们将它添加到XAML中的datagrid:

<DataGrid AutoGenerateColumns="False" FontFamily="Tahoma" FontSize="9"
          ItemsSource="{Binding Path=ResultsVM}" 
          mvvm:SelectedItemsBehavior.SelectedItemsChangedHandler="{Binding Path=ResultsSelectionChangedCommand}" />
Run Code Online (Sandbox Code Playgroud)

然后我们在ViewModel中编写RelayCommand:

    Public ReadOnly Property ResultsSelectionChangedCommand() As mvvm.RelayCommand
        Get
            If _resultsSelectionChangedCommand Is Nothing Then
                _resultsSelectionChangedCommand = New mvvm.RelayCommand(AddressOf ResultsSelectionChanged)
            End If
            Return _resultsSelectionChangedCommand
        End Get
    End Property

    Public Sub ResultsSelectionChanged(ByVal selectedItems As Object)

        _resultsSelectedItems.Clear()
        For Each item In selectedItems
            _resultsSelectedItems.Add(item)
        Next

    End Sub
Run Code Online (Sandbox Code Playgroud)

C#:

public mvvm.RelayCommand ResultsSelectionChangedCommand {
    get {
        if (_resultsSelectionChangedCommand == null) {
            _resultsSelectionChangedCommand = new mvvm.RelayCommand(ResultsSelectionChanged);
        }
        return _resultsSelectionChangedCommand;
    }
}


public void ResultsSelectionChanged(object selectedItems)
{
    _resultsSelectedItems.Clear();
    foreach (item in selectedItems) {
        _resultsSelectedItems.Add(item);
    }

}
Run Code Online (Sandbox Code Playgroud)

_resultsSelectedItems只是DataGrid中显示的项目列表:

    Private _resultsSelectedItems As New List(Of WorkOrderMatchViewModel)
Run Code Online (Sandbox Code Playgroud)

C#:

private List<WorkOrderMatchViewModel> _resultsSelectedItems = new List<WorkOrderMatchViewModel>();
Run Code Online (Sandbox Code Playgroud)

希望这有所帮助,有点使用Bill的方法,而不必参考MVVM-Light.


Bil*_*ell 4

我也一直在寻找这个问题的答案。我找到的答案是

1) 在代码隐藏中将工作委托给 ViewModel 中的方法,传递SelectedItems来自数据网格的列表。该集合将包含所有选定的项目。

或者

2)使用MVVM工具包,它允许您使用Event to Command并将对象作为参数直接传递给ViewModel。

private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    IList lst = this.myDataGrid.SelectedItems;
    ViewModel.RowsSelected(lst);
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您需要将SelectionChangedxaml 中的内容绑定到selectionchanged后面代码中的内容。然后在代码隐藏中,您可以保存此列表并使用它来删除选定的行等。

如果有更好的方法来做到这一点,我很想知道。

华泰

账单