2009-10-16 95 views
9

我正在使用WPF Toolkit的DataGrid。我已经启用了DataGrid上的属性以允许多行选择。我如何获得SelectedItems?我正在使用MVVM框架将我的ViewModel绑定到我的视图。WPF Toolkit DataGrid多选:如何获取SelectedItems?

谢谢!

+0

通过http://stackoverflow.com/a/2615487/284795 – 2012-11-21 14:49:23

回答

4

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

1)在代码隐藏中将工作委托给ViewModel中的方法,从DataGrid传递SelectedItems列表。该集合将包含所选的所有项目。

或者

2)使用MVVM工具包光,使您可以使用事件来指挥并直接传递一个对象作为参数传递给视图模型。

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

在这种情况下,你需要绑定你在你的XAML SelectionChangedselectionchanged在后面的代码。然后在你的代码后面,你可以保存这个列表,并用它来删除选定的行等。

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

HTH

比尔

2

我设法使用命令中继比尔提到的来解决这个问题。这部分内容有点肮脏,但我避免将任何代码放在后面的文件中。首先,在你的XAML中 - 将你的命令绑定到一个按钮上,或者任何触发你的RelayCommand的东西。

<Button Content="Select" 
     cmd:ButtonBaseExtensions.Command="{Binding CommandSelect}" 
     cmd:ButtonBaseExtensions.CommandParameter="{Binding ElementName=Results, Path=SelectedItems}" /> 

您会注意到命令参数绑定到另一个UI元素 - 您希望获得所选项目的DataGrid或ListView。此语法将在Silverlight 3以及WPF中起作用,因为它现在支持元素到元素的绑定。

在您的视图模型的命令会是这个样子

Private _CommandSelect As RelayCommand(Of IEnumerable) 

Public ReadOnly Property CommandSelect() As RelayCommand(Of IEnumerable) 
    Get 
     If _CommandSelect Is Nothing Then 
      _CommandSelect = New RelayCommand(Of IEnumerable)(AddressOf CommandSelectExecuted, AddressOf CommandSelectCanExecute) 
     End If 
     Return _CommandSelect 
    End Get 
End Property 


Private Function CommandSelectExecuted(ByVal parameter As IEnumerable) As Boolean 

    For Each Item As IElectoralAreaNode In parameter 

    Next 

    Return True 
End Function 

Private Function CommandSelectCanExecute() As Boolean 
    Return True 
End Function 

选定的项目将返回一个SelectedItemCollection,但你可能不希望此扶养您的视图模型。因此,将它作为IEnumerable键入并做一点点投射是你唯一的选择,而不是“肮脏”。但它使您的代码保持清洁和MVVM模式!

6

考虑到比尔的答案,合并选项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 

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); 

    } 

} 

然后我们把它添加到数据网格在XAML:

<DataGrid AutoGenerateColumns="False" FontFamily="Tahoma" FontSize="9" 
      ItemsSource="{Binding Path=ResultsVM}" 
      mvvm:SelectedItemsBehavior.SelectedItemsChangedHandler="{Binding Path=ResultsSelectionChangedCommand}" /> 

然后我们在代码中RelayCommand ViewModel:

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 

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); 
    } 

} 

的_resultsSelectedItems简直是在DataGrid中显示的项目清单:

Private _resultsSelectedItems As New List(Of WorkOrderMatchViewModel) 

C#:

private List<WorkOrderMatchViewModel> _resultsSelectedItems = new List<WorkOrderMatchViewModel>(); 

希望这有助于有点同时使用的Bill的方法无需参考MVVM-Light。

+0

部分答案会给予好评这一点,如果它不是在VB.NET书面... :) – 2013-08-28 09:11:48

+0

让我去上工作! – samneric 2013-08-29 16:29:45

+0

我得到的selectedItems不是枚举....'foreach(item in selectedItems)' – Master 2014-03-19 15:38:34

3

C#版本SelectedItemsBehavior类。可能会帮助某人。

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


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

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

    public static void OnSelectedItemsChangedHandlerChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 

     DataGrid dataGrid = (DataGrid)d; 

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

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


    public static void ItemsControl_SelectionChanged(Object sender, SelectionChangedEventArgs e) 
    { 

     DataGrid dataGrid = (DataGrid)sender; 

     RelayCommand itemsChangedHandler = GetSelectedItemsChangedHandler(dataGrid); 

     itemsChangedHandler.Execute(dataGrid.SelectedItems); 
    } 
}