29 votes

Définir dynamiquement le texte de l'en-tête d'une colonne de DataGrid Silverlight

  <my:DataGridTemplateColumn 
            CanUserResize="False" 
            Width="150" 
            Header="{Binding MeetingName, Source={StaticResource LocStrings}}" 
            SortMemberPath="MeetingName"> 
  </my:DataGridTemplateColumn>

J'ai la colonne ci-dessus dans un contrôle de grille Silverlight. Mais je reçois une erreur XamlParser à cause de la façon dont j'essaie de définir la propriété Header. Quelqu'un a-t-il déjà réalisé cette opération ? Je veux le faire pour plusieurs langues.

De plus, la syntaxe de la liaison à une ressource est correcte car je l'ai essayée dans une étiquette en dehors de la grille.

28voto

Adam Kinney Points 871

Vous ne pouvez pas lier l'en-tête car il ne s'agit pas d'un FrameworkElement. Vous pouvez rendre le texte dynamique en modifiant le modèle d'en-tête comme suit :

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>

14voto

RobSiklos Points 3324

Ma solution consistait à utiliser une propriété jointe pour définir automatiquement la liaison :

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

Ensuite, dans le XAML :

<data:DataGridTextColumn util:DataGridColumnHelper.HeaderBinding="{Binding MeetingName, Source={StaticResource LocStrings}}" />

11voto

Lars Holm Jensen Points 699

Pour conserver le style visuel de l'en-tête d'origine, utilisez ContentTemplate au lieu de Template :

<Setter Property="ContentTemplate">
<Setter.Value>
    <DataTemplate>
        <Image Source="<image url goes here>"/>
    </DataTemplate>
</Setter.Value>

2voto

Rudi Points 1541

J'ai trouvé une solution de contournement intéressante qui fonctionne également avec l'option wpflocalizeaddin.codeplex.com :

Créé par Slyi

Il utilise 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;
    }
}

Et un style pour le 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>

de sorte que vous puissiez conserver votre syntaxe de liaison préférée sur la page Header attribut

<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

2voto

Steve Points 39

Il semble en effet beaucoup plus simple de définir la valeur dans le code, comme indiqué ci-dessus :

dg1.Columns[3].Header = SomeDynamicValue;

Évite l'utilisation de la syntaxe Setter Property, qui, dans mon cas, a semblé perturber le style, même si j'ai essayé d'utiliser ContentTemplate ainsi que Template.

Un point sur lequel j'ai glissé, c'est qu'il est préférable d'utiliser l'option dg1.Columns[3].Header plutôt que d'essayer de faire référence à une colonne nommée.

J'avais nommé l'une de mes colonnes et j'ai essayé de la référencer dans le code, mais j'ai obtenu des exceptions nulles. L'utilisation de la méthode Columns[index] a bien fonctionné, et j'ai pu attribuer à l'en-tête une chaîne de texte basée sur les ressources de localisation.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X