Pregunta

En mi Silverlight 3 Control del usuario Estoy mostrando un básico Cuadrícula de datos control. necesito generar las columnas programáticamente como sigue:

Style headerStyle = (Style)Resources["ColumnHeaderStyle"];
DataGridTextColumn col = new DataGridTextColumn();
col.HeaderStyle = headerStyle;
dataGrid.Columns.Add(col);

El estilo se define de la siguiente manera:

<Style x:Name="ColumnStyle" x:Key="ColumnHeaderStyle" 
       TargetType="prim:DataGridColumnHeader">
    <Setter Property="ContentTemplate">
        <Setter.Value>
            <DataTemplate>
                <StackPanel Loaded="StackPanel_Loaded">
                    <TextBlock Text="{Binding Name}" />
                    <TextBlock Text="{Binding Data}" />
                </StackPanel>
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

Yo quiero Establezca el contexto de datos del encabezado en un objeto "encabezado" (con propiedades "Nombre" y "Datos" a las que se hace referencia en la placa de datos). Desafortunadamente, no puedo usar el evento StackPanel_Loaded como se sugiere en otra parte, porque el controlador de eventos también se llama cuando el usuario inicia una operación de arrastre y caída de columna.

¿Cuál es la forma correcta de establecer el DataContext de un encabezado de columna DataGrid?

¿Fue útil?

Solución

Resulta que uno puede usar el Propiedad de encabezado (que es de objeto tipo) como el DataContext para la plantilla de datos (Establecer como se muestra arriba):

Style headerStyle = (Style)Resources["ColumnHeaderStyle"];
DataGridTextColumn col = new DataGridTextColumn();
col.HeaderStyle = headerStyle;
col.Header = myHeaderDataContext; // DataContext for ColumnHeaderStyle
dataGrid.Columns.Add(col);

Otros consejos

Así es como lo harías en XAML (esto funciona en WPF; no estoy seguro de si funciona en SL)

<DataGridTextColumn Binding="{Binding Path=Discount}">
    <DataGridTextColumn.HeaderStyle>
        <Style TargetType="DataGridColumnHeader">
            <Setter Property="Content" Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Path=DataContext.DiscountHeader}" />
        </Style>
    </DataGridTextColumn.HeaderStyle>
</DataGridTextColumn>

Basado en la respuesta de Matt, se me ocurrió la solución de vincular el encabezado en el DataGridCellsPanel que en Snoop parecía tener el contexto de datos correcto:

  <DataGridTemplateColumn.HeaderStyle>
     <Style TargetType="{x:Type DataGridColumnHeader}" BasedOn="{StaticResource CenterAlignedColumnHeaderStyle}">
         <Setter Property="Content" Value="{Binding Path=DataContext.Location, RelativeSource={RelativeSource AncestorType={x:Type DataGridCellsPanel}}}" />
      </Style>
  </DataGridTemplateColumn.HeaderStyle>

Y esto no es intrusivo en la forma en que aún puede heredar de encabezados de estilo personalizado (ver Exemplo arriba) o evento del estilo de encabezado de la columna base:

 <DataGridTemplateColumn.HeaderStyle>
     <Style TargetType="{x:Type DataGridColumnHeader}" BasedOn="{StaticResource {x:Type DataGridColumnHeader}}">
     <Setter Property="Content" Value="{Binding Path=DataContext.Location, RelativeSource={RelativeSource AncestorType={x:Type DataGridCellsPanel}}}" />
     </Style>
 </DataGridTemplateColumn.HeaderStyle>

Esta solución tiene la ventaja de ser XAML puro y limpio y referirse al antepasado más cercano que contiene el DataContext correcto en lugar de tratar de alcanzar DataContext de elementos de jerarquía principales como UserControl.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top