WPF Attached properties

593 views Asked by At

I am trying to implment design time localization I would like a property on the window in Xaml to select the language and language controls that authomatically change their label to show the label in the appropriate language.

The text for the label is looked up by retrieveing the contents of an attached property (LanguageMarkupProperty) on the LanguageLabel that contains a language symbol (LANG_SURNAME or LANG_FORENAME for example), this then gets looked up in the specified language. So far I have created an object deriving from Content control:

public class LanguageLabel : ContentControl
{
    public LanguageLabel()
    {
        EventManager.RegisterClassHandler(typeof(Window),
                                            DisplayLanguage.LanguageChangedEvent,
                                            new RoutedEventHandler(this.ChangeLanguage));

        this.Loaded += new RoutedEventHandler(LanguageLabel_Loaded);
    }

    ~LanguageLabel()
    {
    }

    // Walk up the visual tree to find the top level object.
    private DependencyObject FindUpVisualTree(DependencyObject initial) 
    {
        DependencyObject current = initial;
        DependencyObject last = current;

        while (current != null)
        {
            last = current;
            current = VisualTreeHelper.GetParent(current);
        }

        return last;
    }

    void LanguageLabel_Loaded(object sender, RoutedEventArgs e)
    {
        object root = FindUpVisualTree(this);

        UIElement window = root as UIElement;
        PossibleLanguages ?language = null;
        if (window != null)
            language = (PossibleLanguages)window.GetValue(DisplayLanguage.DisplayLanguageProperty);
        if (language == null) language = PossibleLanguages.UKEnglish;

        string languageSymbol = GetValue(LanguageMarkup.LanguageMarkupProperty) as string;

        this.Content = Language.Translate(languageSymbol, language);

    }

    public void ChangeLanguage(object sender, RoutedEventArgs e)
    {
        LanguageChangedEventArgs le = e as LanguageChangedEventArgs;

        string languageSymbol = GetValue(LanguageMarkup.LanguageMarkupProperty) as string;

        this.Content = Stanley.Language.Translate(languageSymbol, (PossibleLanguages)le.DependencyPropertyChangedEventArgs.NewValue);
    }


}

I have also created an attached property named display language that I am putting on the Window in Xaml.

public class DisplayLanguage
{
    public static readonly DependencyProperty DisplayLanguageProperty;

    public static void SetDisplayLanguage(UIElement element, PossibleLanguages value)
    {
        element.SetValue(DisplayLanguageProperty, value);
    }

    public static PossibleLanguages GetDisplayLanguage(UIElement element)
    {
        return (PossibleLanguages)element.GetValue(DisplayLanguageProperty);
    }

    static DisplayLanguage()
    {
        DisplayLanguageProperty = DependencyProperty.RegisterAttached(
                             "DisplayLanguage",
                             typeof(PossibleLanguages),
                             typeof(WindowBase),
                             new FrameworkPropertyMetadata(PossibleLanguages.UKEnglish, FrameworkPropertyMetadataOptions.AffectsRender ,new PropertyChangedCallback(OnDisplayLanguageChanged))
                             );

    }


    public static void AddReceiver(object receiver, RoutedEventHandler e)
    {
    }

    public static void OnDisplayLanguageChanged(DependencyObject control, DependencyPropertyChangedEventArgs e)
    {
        // Fire an event to tell the LanguageLabel controls to update to the new language.
    }

}

I would like OnDisplayLanguageChanged to raise an event somehow that tells all the language controls to update their display at design time. Does anyone know how I can acheiev this?

1

There are 1 answers

1
Pavlo Glazkov On BEST ANSWER

You can use something like EventAggregator in Prism or Messanger in MVVMLight to broadcast an event to which all language controls can subscribe.

If you don't want to use these frameworks it is quite easy to create you own implementation of this pattern.