necesario - silverlight para mac
Configuración dinámica del texto del encabezado de una columna Silverlight DataGrid (8)
<my:DataGridTemplateColumn
CanUserResize="False"
Width="150"
Header="{Binding MeetingName, Source={StaticResource LocStrings}}"
SortMemberPath="MeetingName">
</my:DataGridTemplateColumn>
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 sintaxis para el enlace a un recurso es correcta porque lo probé en una etiqueta fuera de la cuadrícula.
¿Por qué no simplemente configurar esto en código?
dg1.Columns[3].Header = SomeDynamicValue;
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
<UserControl.Resources>
<local:BindingConverter x:Key="BindCon"/>
<Style x:Key="ColBinding" TargetType="dataprimitives:DataGridColumnHeader" >
<Setter Property="ContentTemplate" >
<Setter.Value>
<DataTemplate>
<ContentPresenter Content="{Binding Converter={StaticResource BindCon}}" />
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
para que pueda mantener su sintaxis de enlace favorita en el atributo de Header
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel>
<TextBox Text="binding header" x:Name="tbox" />
<data:DataGrid ItemsSource="{Binding AllPeople,Source={StaticResource folks}}" AutoGenerateColumns="False" ColumnHeaderStyle="{StaticResource ColBinding}" >
<data:DataGrid.Columns>
<data:DataGridTextColumn Binding="{Binding ID}"
Header="{Binding Text, ElementName=tbox}" />
<data:DataGridTextColumn Binding="{Binding Name}"
Header="hello" />
</data:DataGrid.Columns>
</data:DataGrid>
</StackPanel>
</Grid>
http://cid-289eaf995528b9fd.skydrive.live.com/self.aspx/Public/HeaderBinding.zip
Mi solución fue usar 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:
<data:DataGridTextColumn util:DataGridColumnHelper.HeaderBinding="{Binding MeetingName, Source={StaticResource LocStrings}}" />
No se puede vincular al encabezado porque no es un elemento estructural. Puede hacer que el texto sea dinámico 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"
<data:DataGridTemplateColumn>
<data:DataGridTemplateColumn.HeaderStyle>
<Style TargetType="dataprimitives:DataGridColumnHeader">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<TextBlock Text="{Binding MeetingName, Source={StaticResource LocStrings}}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</data:DataGridTemplateColumn.HeaderStyle>
</data:DataGridTemplateColumn>
Para mantener el estilo visual del encabezado original, use ContentTemplate en lugar de Template:
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Image Source="<image url goes here>"/>
</DataTemplate>
</Setter.Value>
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 sintaxis 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.
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.