2010-06-17 32 views
18

Estoy buscando cómo crear las columnas de DataGrid desde la dinámica de ToolKit en modo MvvM. ¡Pero parece que es imposible!Columnas dinámicas WPF MvvM DataGrid

¿Hay alguien que tenga que hacer lo mismo?

no hay necesidad de crear un control de usuario u otro control que provenga de DataGrid, solo quiero establecer de ItemSource de la grilla en mi objeto personalizado y en algún punto quiero definir las columnas de la grilla en tiempo de ejecución dinámico basado en el tipo de objeto

¿Es esto posible?

aplausos

Respuesta

9

Voy a aclarar esto diciendo que tal vez no es la mejor solución para estar haciendo y puede no funcionar en algunas situaciones, pero usted puede darle una oportunidad y ver si se va a trabajar para Lo que quieras. Simplemente preparé esto para que tenga algunos errores. Todavía implicará algún código, pero evita que tu modelo conozca tu visión.

Lo que debe hacer es crear una propiedad de extensión que le permita vincular la propiedad Columns en DataGrid. Aquí hay un ejemplo que armé.

using System.Collections.ObjectModel; 
using System.Collections.Specialized; 
using System.Windows; 
using System.Windows.Controls; 

public static class DataGridExtension 
{ 
    public static ObservableCollection<DataGridColumn> GetColumns(DependencyObject obj) 
    { 
     return (ObservableCollection<DataGridColumn>)obj.GetValue(ColumnsProperty); 
    } 

    public static void SetColumns(DependencyObject obj, ObservableCollection<DataGridColumn> value) 
    { 
     obj.SetValue(ColumnsProperty, value); 
    } 

    public static readonly DependencyProperty ColumnsProperty = 
      DependencyProperty.RegisterAttached("Columns", 
      typeof(ObservableCollection<DataGridColumn>), 
      typeof(DataGridExtension), 
      new UIPropertyMetadata (new ObservableCollection<DataGridColumn>(), 
      OnDataGridColumnsPropertyChanged)); 


    private static void OnDataGridColumnsPropertyChanged(
      DependencyObject d, 
      DependencyPropertyChangedEventArgs e) 
    { 
     if (d.GetType() == typeof(DataGrid)) 
     { 
      DataGrid myGrid = d as DataGrid; 

      ObservableCollection<DataGridColumn> Columns = 
       (ObservableCollection<DataGridColumn>)e.NewValue; 

      if(Columns != null) 
      { 
       myGrid.Columns.Clear(); 

       if (Columns != null && Columns.Count > 0) 
       { 
        foreach (DataGridColumn dataGridColumn in Columns) 
        { 
         myGrid.Columns.Add(dataGridColumn); 
        } 
       } 


       Columns.CollectionChanged += delegate(object sender, 
           NotifyCollectionChangedEventArgs args) 
        { 
         if(args.NewItems != null) 
         { 
         foreach (DataGridColumn column 
           in args.NewItems.Cast<DataGridColumn>()) 
         { 
          myGrid.Columns.Add(column); 
         } 
         } 

         if(args.OldItems != null) 
         { 
         foreach (DataGridColumn column 
           in args.OldItems.Cast<DataGridColumn>()) 
         { 
          myGrid.Columns.Remove(column); 
         } 
         } 
        }; 
      } 
     } 
    } 
} 

A continuación se adjunta a usted cuadrícula de datos del modo siguiente (columnas es la propiedad de un ObservableCollection en su modelo de vista)

<Controls:DataGrid AutoGenerateColumns="False" 
      DataGridExtension.Columns="{Binding Columns}" /> 

No estoy seguro de lo bien que va a responder si empiezo a agregar y eliminar columnas, pero parece funcionar a partir de mis pruebas básicas. ¡Buena suerte!

+1

El código anterior hará el trabajo en general. Sin embargo, fallará cuando oculte la cuadrícula de datos y la vuelva a hacer visible. Debido a que la propiedad de columnas mostrará que hay 0 columnas cuando están ocultas y cuando se cambia la propiedad de las columnas, se activará la devolución de llamada e intentará agregar las columnas nuevamente, pero físicamente existen columnas en la cuadrícula de datos para que el código fallar con una excepción que dice que no se pueden agregar columnas duplicadas. –

1

Al tener un problema similar, no quería agregar otra propiedad de dependencia. Mi solución fue organizar los datos para mostrar en el DataGrid en una DataTable y enlazar la propiedad DataGrid ItemSource a esta DataTable (con por supuesto AutoGenerateColumns establecido en verdadero).

Funciona bien, DataGrids parece feliz con DataTable como fuente.

+0

DataGrid.ItemSource no acepta una DataTable. Dice que no es un IEnumerable ... (.Net 4.5) –

+0

Creé el proyecto con 4.5 y no me dio ningún error. Ato el recurso de elemento de la cuadrícula de datos en xaml: 'ItemsSource =" {Binding ResultsViewerValues} "', donde ResultsViewerValues ​​es propiedad (DataTable) en el modelo de vista – user3189858