Warning : This page has been marked as an archive because the author consider that its content is no longer relevant.

Lorsqu’on développe une application localisable en Silverlight on utilise souvent des fichiers ressources (extension .resx) pour stocker nos textes. Afin d’y accéder en XAML on utilise généralement la syntaxe suivante :

<TextBlock
    Text="{Binding Strings.ApplicationName, Source={StaticResource AppStrings}}" />

Cependant une telle technique ne fonctionne pas avec la propriété Header des DataColumn. Il est donc impossible d’écrire le code suivant :

<sdk:DataGridTextColumn
    Header="{Binding Strings.UserGrid_FirstName, Source={StaticResource AppStrings}}"
    Binding="{Binding FirstName}" />

Afin de contourner le problème j’ai créé un Behavior qui va se charger d’aller affecter le texte à la propriété header de la DataColumn. Il s’utilise de la manière suivante :

<sdk:DataGridTextColumn Binding="{Binding FirstName}">
    <i:Interaction.Behaviors>
        <b:LocalizeDataGridColumnHeaderBehavior
            Source="{StaticResource AppStrings}"
            Path="Strings.UserGrid_FirstName" />
    </i:Interaction.Behaviors>
</sdk:DataGridTextColumn>

Voici le code du dit Behavior :

public class LocalizeDataGridColumnHeaderBehavior : Behavior<DataGridColumn>
{
    public static readonly DependencyProperty SourceProperty =
        DependencyProperty.Register("Source", typeof(object),
        typeof(LocalizeDataGridColumnHeaderBehavior), new PropertyMetadata(null));
    public static readonly DependencyProperty PathProperty =
        DependencyProperty.Register("Path", typeof(string),
        typeof(LocalizeDataGridColumnHeaderBehavior), new PropertyMetadata(null));

    public object Source
    {
        get { return GetValue(SourceProperty); }
        set { SetValue(SourceProperty, value); }
    }

    public string Path
    {
        get { return (string)GetValue(PathProperty); }
        set { SetValue(PathProperty, value); }
    }

    private static object ResolveObject(object source, string path)
    {
        bool loop = true;

        while (loop)
        {
            int indexOfPoint = path.IndexOf('.');

            if (indexOfPoint > -1)
            {
                string propertyName = path.Substring(0, indexOfPoint);
                PropertyInfo propertyInfo = source.GetType().GetProperty(propertyName);
                source = propertyInfo.GetValue(source, null);
                path = path.Substring(indexOfPoint + 1);
            }
            else
            {
                PropertyInfo propertyInfo = source.GetType().GetProperty(path);
                source = propertyInfo.GetValue(source, null);
                loop = false;
            }
        }

        return source;
    }

    protected override void OnAttached()
    {
        base.OnAttached();

        if (string.IsNullOrEmpty(Path))
            return;

        AssociatedObject.Header = ResolveObject(Source, Path) as string;

        Detach();
    }
}

Comme d’habitude vous trouverez le projet d’exemple sur mon skydrive.

Comments