私は WPF Toolkit の DataGrid を使用しています。行の複数選択を可能にするために、DataGrid のプロパティを有効にしました。SelectedItems を取得するにはどうすればよいですか? ViewModel を View にバインドするために MVVM フレームワークを使用しています。
ありがとう!
私は WPF Toolkit の DataGrid を使用しています。行の複数選択を可能にするために、DataGrid のプロパティを有効にしました。SelectedItems を取得するにはどうすればよいですか? ViewModel を View にバインドするために 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}" />
次に、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
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>();
これがお役に立てば幸いです。MVVM-Lightを参照しなくても、Billの両方の方法を使用できます。
私もこの質問に対する答えを探していました。私が見つけた答えは、
SelectedItems
1) 分離コードで、データグリッドからリストを渡す ViewModel のメソッドに作業を委譲します。このコレクションには、選択されたすべてのアイテムが含まれます。
または
2) MVVM ツールキット ライトを使用して、Event to Command を使用し、オブジェクトをパラメータとして ViewModel に直接渡すことができます。
private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
IList lst = this.myDataGrid.SelectedItems;
ViewModel.RowsSelected(lst);
}
この場合SelectionChanged
、xamlselectionchanged
内の をコード ビハインド内の にバインドする必要があります。次に、コード ビハインドでこのリストを保存し、選択した行の削除などに使用できます。
これを行うためのより良い方法があれば、私は知りたいです。
HTH
明細書
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);
}
}
Bill が述べたように、リレー コマンドを使用してこれを回避することができました。部分的に少し汚れていますが、ビハインド ファイルにコードを入れることは避けました。
まず、XAML で、コマンドをボタンまたは RelayCommand をトリガーするものにバインドします。
<Button Content="Select"
cmd:ButtonBaseExtensions.Command="{Binding CommandSelect}"
cmd:ButtonBaseExtensions.CommandParameter="{Binding ElementName=Results, Path=SelectedItems}" />
コマンド パラメーター Binds が別の UI 要素 (選択した項目を取得する DataGrid または ListView) にあることに気付くでしょう。この構文は、要素間のバインディングをサポートするようになったため、WPF だけでなく Silverlight 3 でも機能します。
ビューモデルでは、コマンドは次のようになります
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 パターンをそのまま維持します。