我正在使用WPF Toolkit的DataGrid。我已經啓用了DataGrid上的屬性以允許多行選擇。我如何獲得SelectedItems?我正在使用MVVM框架將我的ViewModel綁定到我的視圖。WPF Toolkit DataGrid多選:如何獲取SelectedItems?
謝謝!
我正在使用WPF Toolkit的DataGrid。我已經啓用了DataGrid上的屬性以允許多行選擇。我如何獲得SelectedItems?我正在使用MVVM框架將我的ViewModel綁定到我的視圖。WPF Toolkit DataGrid多選:如何獲取SelectedItems?
謝謝!
我一直在尋找這個問題的答案。我找到的答案是
1)在代碼隱藏中將工作委託給ViewModel中的方法,從DataGrid傳遞SelectedItems
列表。該集合將包含所選的所有項目。
或者
2)使用MVVM工具包光,使您可以使用事件來指揮並直接傳遞一個對象作爲參數傳遞給視圖模型。
private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
IList lst = this.myDataGrid.SelectedItems;
ViewModel.RowsSelected(lst);
}
在這種情況下,你需要綁定你在你的XAML SelectionChanged
您selectionchanged
在後面的代碼。然後在你的代碼後面,你可以保存這個列表,並用它來刪除選定的行等。
如果有更好的方法來做到這一點,我很想知道是否是好的。
HTH
比爾
我設法使用命令中繼比爾提到的來解決這個問題。這部分內容有點骯髒,但我避免將任何代碼放在後面的文件中。首先,在你的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模式!
考慮到比爾的答案,合併選項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。
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);
}
}
通過http://stackoverflow.com/a/2615487/284795 – 2012-11-21 14:49:23