2009-10-16 18 views
9

私はWPF ToolkitのDataGridを使用しています。 DataGridのプロパティを有効にして、行を複数選択できるようにしました。 SelectedItemをどのように取得するのですか? MVVMフレームワークを使用してViewModelをビューにバインドしています。WPF Toolkit DataGrid Multi-Select:SelectedItemsを取得する方法?

ありがとうございます!

+0

は...それはVB.NETで書かれていなかった場合は、これをupvoteだろうhttp://stackoverflow.com/a/2615487/284795 –

答えて

4

私はこの質問にも答えを探しています。私が見つけた答えは

です。1)コードビハインドでは、データグリッドからSelectedItemsリストを渡すViewModelのメソッドに作業を委譲します。このコレクションには、選択されているすべてのアイテムが含まれます。

それとも )は、コマンドにイベントを使用してのViewModelに直接オブジェクトをパラメータとして渡すことができますMVVMツールキット光を使用しています。あなたはあなたのXAMLでSelectionChangedをあなたのコード内のselectionchangedが背後にバインドする必要があります。この場合

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

。あなたのコードビハインドでは、このリストを保存して、選択した行などを削除するために使用できます。

これを行うより良い方法があれば、私はよく知っていればよいと思います。

HTH

ビル

2

私はビルが述べたようにリレーのコマンドを使用してこの問題を回避するために管理。それは少し汚れていますが、後ろのファイルにコードを書くことは避けました。

まず、ボタンにコマンドをバインドするか、RelayCommandをトリガーするものをXAMLにバインドします。

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

コマンドパラメータには、選択した項目を取得するDataGridまたはListViewという別のUI要素にバインドされていることがあります。この構文は、要素から要素へのバインディングをサポートしているため、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パターンをそのままにします!

6

オプション1と2をマージしてBillの答えを得て、コードビハインドの代わりに添付プロパティを振りかざすと、私はBehaviorを思いついた。

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は、単にデータグリッドに表示される項目のリストである:

Private _resultsSelectedItems As New List(Of WorkOrderMatchViewModel) 

C#:

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

希望これはちょっとの両方を使用して、助けMVVM-Lightを参照する必要がないBillのメソッド

+0

により部分的に回答:) –

+0

は、私はその上で動作するように取得してみましょう! – samneric

+0

selectedItemsは列挙型ではありません.... 'foreach(item in selectedItems)' – Master

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); 
    } 
} 
関連する問題