2011-09-29 11 views
5

Tengo un control personalizado que hereda de DataGrid y es básicamente un 2D DataGrid (acepta un ItemsSource con dos dimensiones, como double[,]).Force WPF DataGrid para regenerarse a sí mismo

He añadido un específico DependencyProperty que es ColumnHeaders y RowHeaders así que puedo definirlos.

Aquí es cómo funciona en este momento:

  • Ato un 2D ItemsSource a la DataGrid
  • Un método de envoltura se llevará a esta fuente para transformarla en un clásico IEnumerable enlazable a la cuadrícula de datos reales de ItemsSource
  • Cada fila/columna de auto-generado se hace usando los eventos AutoGeneratingColumn & AutoGeneratingRow con el fin de definir su cabecera

El problema aquí:

Cuando inicializar el DataGrid, todo funciona bien.

Después de eso, uno de los casos de uso de mi solicitud define que sólo los encabezados de columna pueden cambiar (mediante la modificación del DependencyPropertyColumnHeaders

Y, haga lo que haga aquí, el DataGrid no va a volver a su AutoGenerate columnas (y por lo tanto, los encabezados no se cambiarán de ninguna manera).

Entonces, ¿hay alguna manera de preguntarle al DataGrid algo así como "Hola, quiero que reinicies desde cero y regeneres tus columnas"? Porque ahora, no puedo alcanzar el evento AutoGeneratingColumn, y llamar a un método como InvalidateVisual simplemente volverá a dibujar la cuadrícula (y no regenerar columnas).

¿Alguna idea aquí?

no estoy seguro de que necesitamos algo de código, pero ... Voy a poner algo de lo que nadie lo pide: D

/// <summary> 
    /// IList of String containing column headers 
    /// </summary> 
    public static readonly DependencyProperty ColumnHeadersProperty = 
     DependencyProperty.Register("ColumnHeaders", 
            typeof(IEnumerable), 
            typeof(FormattedDataGrid2D), 
            new PropertyMetadata(HeadersChanged)); 

    /// <summary> 
    /// Handler called when the binding on ItemsSource2D changed 
    /// </summary> 
    /// <param name="source"></param> 
    /// <param name="e"></param> 
    private static void ItemsSource2DPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e) 
    { 
     FormattedDataGrid2D @this = source as FormattedDataGrid2D; 
     @this.OnItemsSource2DChanged(e.OldValue as IEnumerable, e.NewValue as IEnumerable); 
    } 

     // (in the constructor) 
     AutoGeneratingColumn += new EventHandler<DataGridAutoGeneratingColumnEventArgs>(DataGrid2D_AutoGeneratingColumn); 

    void DataGrid2D_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) 
    { 
     DataGridTextColumn column = e.Column as DataGridTextColumn; 
     column.Header = (ColumnHeaders == null) ? columnIndex++ : (ColumnHeaders as IList)[columnIndex++]; //Header will be the defined header OR the column number 
     column.Width = new DataGridLength(1.0, DataGridLengthUnitType.Auto); 
     Binding binding = column.Binding as Binding; 
     binding.Path = new PropertyPath(binding.Path.Path + ".Value"); // Workaround to get a good value to display, do not take care of that 
    } 
+0

por qué no intentar restablecer la propiedad ItemsSource –

+0

En realidad funciona (y no puedo creer que no he pensado en eso antes -__-), pero ¿hay alguna manera "inteligente" para hacer eso? – Damascus

+0

@Damascus ¿Ha encontrado una manera más inteligente que desconectar y configurar elementos? Estoy buscando eso también. – Haozhun

Respuesta

6

Restablecer el ItemsSource y debe volver a dibujar el DataGrid

void ResetDataGrid() 
{ 
    var temp = myDataGrid.ItemsSource; 
    myDataGrid.ItemsSource = null; 
    myDataGrid.ItemsSource = temp; 
} 

es posible que también sea capaz de actualizar la unión, pero yo no lo he probado para ver si esto va a regenerar la cuadrícula de datos:

void ResetDataGrid() 
{ 
    myDataGrid.GetBindingExpression(DataGrid.ItemsSourceProperty).UpdateTarget(); 
} 
+0

Hola, La actualización no funcionará ya que WPF comprobará automáticamente si la propiedad enlazada realmente ha cambiado (que no es el caso) Restablecer elementos funciona bien, pero me preguntaba si no hay una solución "más elegante" ? – Damascus

3

Alternar Autogenerated Columns apagado y luego encendido hará que las columnas se generen automáticamente de nuevo.

dataGrid.AutoGenerateColumns = false; 
dataGrid.AutoGenerateColumns = true; 
+0

Tengo un escenario similar al OP y esta solución funcionó mejor que la otra solución. Por alguna razón, el desorden directo con ItemsSource hizo que la autogeneración no funcionara. –