Configuración dinámica del texto del encabezado de una columna Silverlight DataGrid

  

Tengo la columna de arriba en un control de cuadrícula de Silverlight. Pero me está dando un error XamlParser debido a la forma en que estoy tratando de establecer la propiedad Header. ¿Alguien ha hecho esto antes? Quiero hacer esto para varios idiomas.

También mi syntax para el enlace a un recurso es correcta porque lo probé en una etiqueta fuera de la cuadrícula.

No se puede vincular al encabezado porque no es un elemento estructural. Puede hacer que el texto sea dynamic modificando la Plantilla de encabezado de esta manera:

 xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" xmlns:dataprimitives="clr-namespace:System.Windows.Controls.Primitives;assembly=System.Windows.Controls.Data"      

Mi solución fue utilizar una propiedad adjunta para establecer el enlace automáticamente:

 public static class DataGridColumnHelper { public static readonly DependencyProperty HeaderBindingProperty = DependencyProperty.RegisterAttached( "HeaderBinding", typeof(object), typeof(DataGridColumnHelper), new PropertyMetadata(null, DataGridColumnHelper.HeaderBinding_PropertyChanged)); public static object GetHeaderBinding(DependencyObject source) { return (object)source.GetValue(DataGridColumnHelper.HeaderBindingProperty); } public static void SetHeaderBinding(DependencyObject target, object value) { target.SetValue(DataGridColumnHelper.HeaderBindingProperty, value); } private static void HeaderBinding_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { DataGridColumn column = d as DataGridColumn; if (column == null) { return; } column.Header = e.NewValue; } } 

Entonces, en el XAML:

  

Para mantener el estilo visual del encabezado original, use ContentTemplate en lugar de Template:

       

Encontré una solución interesante que también funciona con wpflocalizeaddin.codeplex.com :

Creado por Slyi

Utiliza un IValueConverter :

 public class BindingConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value.GetType().Name == "Binding") { ContentControl cc = new ContentControl(); cc.SetBinding(ContentControl.ContentProperty, value as Binding); return cc; } else return value; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { return null; } } 

Y un estilo para el DataGridColumnHeader

     

para que pueda mantener su syntax de enlace favorita en el atributo de Header

            

http://cid-289eaf995528b9fd.skydrive.live.com/self.aspx/Public/HeaderBinding.zip

Parece mucho más simple establecer el valor en el código, como se mencionó anteriormente:

 dg1.Columns[3].Header = SomeDynamicValue; 

Evita el uso de la syntax de la propiedad Setter, que en mi caso parecía arruinar el diseño, aunque intenté usar ContentTemplate y Template.

Un punto en el que me dg1.Columns[3].Header fue que es mejor utilizar la dg1.Columns[3].Header lugar de tratar de hacer referencia a una columna con nombre.

Había nombrado una de mis columnas e intenté hacer referencia a eso en el código, pero obtuve excepciones nulas. Usar el método Columns [index] funcionó bien, y pude asignarle al encabezado una cadena de texto basada en los recursos de localización.

¿Por qué no simplemente configurar esto en código?

 dg1.Columns[3].Header = SomeDynamicValue; 

Tenga en cuenta que en la solución proporcionada por RobSiklos, Source {staticResource …} es la clave, si planea pasar el RelativeSource como

 Binding DataContext.SelectedHistoryTypeItem,RelativeSource={RelativeSource AncestorType=sdk:DataGrid}, 

puede que no funcione

Tengo alguna solución para el enlace. Como usa DataGridTemlateColumn, subclasselo y agregue una propiedad de tipo Binding con el nombre, por ejemplo, “HeaderBinding”. Ahora puede enlazar a esa propiedad desde el XAML. A continuación, debe propagar el enlace al TextBlock en el DataTemplate de su encabezado. Por ejemplo, puede hacerlo con el evento OnLoaded de ese TextBlock.

  HeaderTextBlock.SetBinding(TextBlock.TextProperty, HeaderBinding); 

Eso es. Si tiene más columnas y desea usar solo una DataTemplate, entonces es un poco más complicado, pero la idea es la misma.