2010-04-10 16 views
14

Tengo una cuadrícula de datos habilitada para varias selecciones. Necesito cambiar la selección en el modelo de vista. Sin embargo, la propiedad SelectedItems es de solo lectura y no puede vincularse directamente a una propiedad en el modelo de vista. Entonces, ¿cómo señalo a la vista que la selección ha cambiado?WPF DataGrid enlace múltiple selectivo

+0

Véase también http://stackoverflow.com/questions/1579700/wpf-toolkit-datagrid-multi-select-how-to-get-selecteditems-out –

Respuesta

6

no he trabajado con el DataGrid mucho, pero una técnica que trabaja para el ListView es de obligar a la propiedad IsSelected del individuo ListViewItem. Simplemente configure esto en true para cada objeto en su lista, y luego será seleccionado.

Tal vez el objeto que representa una fila en el DataGrid también tiene una propiedad IsSelected, ¿y también se puede usar de esta manera?

17

Andy es correcto. DataGridRow.IsSelected es una Propiedad de Dependencia que se puede unir a datos para controlar la selección del Modelo de Vista. El siguiente código de ejemplo muestra lo siguiente:

<Window x:Class="DataGridMultiSelectSample.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:tk="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit" 
    Title="Window1" Height="300" Width="300"> 
    <StackPanel> 
     <tk:DataGrid AutoGenerateColumns="False" ItemsSource="{Binding}" EnableRowVirtualization="False"> 
      <tk:DataGrid.Columns> 
       <tk:DataGridTextColumn Header="Value" Binding="{Binding Value}" /> 
      </tk:DataGrid.Columns> 
      <tk:DataGrid.RowStyle> 
       <Style TargetType="tk:DataGridRow"> 
        <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" /> 
       </Style> 
      </tk:DataGrid.RowStyle> 
     </tk:DataGrid> 
     <Button Content="Select Even" Click="Even_Click" /> 
     <Button Content="Select Odd" Click="Odd_Click" /> 
    </StackPanel> 
</Window> 

using System.ComponentModel; 
using System.Windows; 

namespace DataGridMultiSelectSample 
{ 
    public partial class Window1 
    { 
     public Window1() 
     { 
      InitializeComponent(); 
      DataContext = new[] 
           { 
            new MyViewModel {Value = "Able"}, 
            new MyViewModel {Value = "Baker"}, 
            new MyViewModel {Value = "Charlie"}, 
            new MyViewModel {Value = "Dog"}, 
            new MyViewModel {Value = "Fox"}, 
           }; 
     } 

     private void Even_Click(object sender, RoutedEventArgs e) 
     { 
      var array = (MyViewModel[]) DataContext; 
      for (int i = 0; i < array.Length; ++i) 
       array[i].IsSelected = i%2 == 0; 
     } 

     private void Odd_Click(object sender, RoutedEventArgs e) 
     { 
      var array = (MyViewModel[])DataContext; 
      for (int i = 0; i < array.Length; ++i) 
       array[i].IsSelected = i % 2 == 1; 
     } 
    } 

    public class MyViewModel : INotifyPropertyChanged 
    { 
     public string Value { get; set; } 

     private bool mIsSelected; 
     public bool IsSelected 
     { 
      get { return mIsSelected; } 
      set 
      { 
       if (mIsSelected == value) return; 
       mIsSelected = value; 
       if (PropertyChanged != null) 
        PropertyChanged(this, new PropertyChangedEventArgs("IsSelected")); 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 
    } 
} 

Asegúrese de ajustar EnableRowVirtualisation="False" en el elemento de cuadrícula de datos, de lo contrario existe el riesgo de que los enlaces IsSelected caen fuera de orden.

+0

perfecto. Y gracias por el código de muestra: lo ilustra muy bien. –

+0

Gracias. Espero que no te importe agregar 'EnableRowVirtualisation =" False "' a tu ejemplo, porque sin él, hay un error en el que el enlace no está en las filas nuevas. –

3

Chicos, gracias por la ayuda. Mi problema fue resuelto Creo que el problema es bastante común para los nuevos desarrolladores de WPF, por lo que voy a replantear mi problema y la solución en más detalles aquí en caso de que alguien más se encuentre con el mismo tipo de problemas.

El problema: tengo una cuadrícula de datos de selección múltiple de archivos de audio. La grilla tiene múltiples encabezados de columna. El usuario puede seleccionar varias filas varias veces. Cuando hace clic en el botón Reproducir, los archivos de audio se reproducirán en el orden uno de los encabezados de las columnas (por ejemplo, la columna A). Cuando se inicia la reproducción, la selección múltiple se borra y solo se resalta el archivo que se está reproduciendo en ese momento. Cuando finalice la reproducción de todos los archivos, se volverá a mostrar la selección múltiple. La reproducción se realiza en el modelo de vista. Como puede ver, aquí hay dos problemas: 1) cómo seleccionar el archivo que se está reproduciendo desde el modelo de vista, y 2) cómo señalar a la vista desde el modelo de vista que la reproducción ha finalizado y volver a mostrar la selección múltiple.

La solución: Para resolver el primer problema, creé una propiedad en el modelo de vista que está vinculada a la propiedad SelectedIndex de la vista para seleccionar el archivo que se está reproduciendo actualmente. Para resolver el segundo problema, creé una propiedad booleana en el modelo de vista para indicar que la reproducción ha finalizado. En el código de la vista detrás, suscribí el evento PropertyChanged de la propiedad booleana. En el controlador de eventos, la propiedad SelectedItems de la vista se vuelve a crear a partir de la selección múltiple guardada (el contenido de SelectedItems se guardó en una lista y SelectedItems se borró cuando comenzó la reproducción). Al principio, tuve problemas para volver a crear SelectedItems. Resultó que el problema se debía al hecho de que la recreación se inició a través de un segundo hilo. WPF no permite eso. La solución a esto es usar Dispatcher.Invoke() para permitir que el hilo principal haga el trabajo. Este puede ser un problema muy simple para los desarrolladores experimentados, pero para los novatos, es un pequeño desafío. De todos modos, mucha ayuda de diferentes personas.

2

Simplemente use SelectedItems en cualquier clase derivada de MultiSelector, y use los métodos Add, Remove, Clear on IList return.

Saludos, Robin