Pergunta

No meu Silverlight 3 Controle do usuário Estou mostrando um básico Grade de dados ao controle. Preciso gerar as colunas programaticamente do seguinte modo:

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

O estilo é definido da seguinte maneira:

<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>

Eu quero Defina o contexto de dados do cabeçalho para um objeto "cabeçalho" (com propriedades "nome" e "dados" que são referenciadas no datatemplate). Infelizmente, não posso usar o evento Stackpanel_loaded, conforme sugerido em outro lugar, porque o manipulador de eventos também é chamado quando o usuário inicia uma operação de arrastar e soltar em coluna.

Qual é a maneira correta de definir o datacontext de um cabeçalho de coluna Datagrid?

Foi útil?

Solução

Acontece que se pode usar o Propriedade do cabeçalho (que é do objeto de tipo) como o DataContext para o Datatemplate (definido como mostrado acima):

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

Outras dicas

Veja como você faria isso em xaml (isso funciona no WPF; não tenho certeza se funciona no 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>

Com base na resposta de Matt, criei a solução de ligar o cabeçalho no DataGridCellsPanel que em Snoop parecia ter o contexto de dados correto:

  <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>

E isso não é intrusivo na maneira como você ainda pode herdar de cabeçalhos de estilo personalizado (veja exemplos acima) ou evento o estilo de cabeçalho da coluna 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 solução tem a vantagem de ser XAML pura e limpa e se referir ao ancestral mais próximo que segura o datacontext correto, em vez de tentar alcançar o DataContext dos elementos de hierarquia superior, como o UserControl.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top