2009-10-16 17 views

Respuesta

4

He estado buscando una respuesta a esta pregunta también. Las respuestas que he encontrado son

1) en el código detrás de delegar el trabajo a un método en el modelo de vista que pasa la lista SelectedItems de la cuadrícula de datos. Esta colección contendrá todos los elementos seleccionados.

O

2) utilizar el kit de herramientas de la luz MVVM que le permite utilizar el evento de Mando y pasa un objeto como un parámetro directamente al modelo de vista.

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

En este caso tendrá que vincular a su SelectionChanged en su xaml a su selectionchanged en el código subyacente. Luego, en su código subyacente, puede guardar esta lista y usarla para eliminar filas seleccionadas, etc.

Si hay una forma mejor de hacerlo, me gustaría saber si está bien.

HTH

Bill

2

he conseguido alrededor de este uso de los Comandos de relé como Bill mencionó. Está un poco sucio en algunas partes, pero evité poner cualquier código en el archivo detrás.

En primer lugar, en su XAML - Enlace su comando a un botón, o lo que sea que desencadena su RelayCommand.

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

Se dará cuenta el parámetro del comando se une a otro de los elementos de interfaz de usuario - la cuadrícula de datos o ListView, quieren obtener los elementos seleccionados de. Esta sintaxis funcionará tanto en Silverlight 3 como en WPF, ya que ahora admite el enlace de elemento a elemento.

En su modelo de vista de su comando se verá algo como esto

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 

Los elementos seleccionados serán devueltos como SelectedItemCollection, pero es probable que no desee que esta dependencia en su vista del modelo. Así que escribirlo como IEnumerable y hacer un poco de casting es tu única opción, ya que es la 'suciedad'. ¡Pero mantiene su código limpio y el patrón MVVM intacto!

6

Tomando la respuesta de Bill, combinando las opciones 1 y 2, agregando una pizca de propiedades adjuntas como alternativa a la escritura de código subyacente, se me ocurrió un Comportamiento.

En primer lugar, tenemos el comportamiento:

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

    } 

} 

Luego lo añadimos a la cuadrícula de datos en XAML:

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

Luego de Códigos El RelayCommand en 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); 
    } 

} 

Los _resultsSelectedItems es simplemente una lista de artículos que aparece en la cuadrícula de datos:

Private _resultsSelectedItems As New List(Of WorkOrderMatchViewModel) 

C#:

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

Espero que esto ayude, un poco utiliza ambos Los métodos de Bill sin tener que hacer referencia a MVVM-Light.

+0

Me upvote esto si no estaba escrito en VB.NET ... :) –

+0

Vamos a conseguir que trabajar en eso! – samneric

+0

obtengo SelectedItems no es una enumeración .... 'foreach (item in selectedItems)' – Master

3

C# version SelectedItemsBehavior class. Puede ser ayudar a alguien.

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