【问题标题】:WPF Attached propertiesWPF 附加属性
【发布时间】:2025-07-17 08:10:01
【问题描述】:

我正在尝试实现设计时本地化我想在 Xaml 中的窗口上使用一个属性来选择自动更改其标签的语言和语言控件,以便以适当的语言显示标签。

通过检索包含语言符号(例如 LANG_SURNAME 或 LANG_FORENAME)的 LanguageLabel 上的附加属性 (LanguageMarkupProperty) 的内容来查找标签的文本,然后以指定的语言进行查找。到目前为止,我已经创建了一个派生自 Content 控件的对象:

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


}

我还创建了一个名为 display language 的附加属性,我将它放在 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.
    }

}

我希望 OnDisplayLanguageChanged 以某种方式引发一个事件,告诉所有语言控件在设计时更新它们的显示。有谁知道我怎么能做到这一点?

【问题讨论】:

  • “设计时本地化”是什么意思?
  • 我的意思是xaml在VS IDE中渲染的人
  • 密钥错误。再试一次。我的意思是 VS2010 中的设计时渲染显示带有适当语言翻译的标签。

标签: wpf localization attached-properties


【解决方案1】:

您可以使用EventAggregator in PrismMessanger in MVVMLight 之类的东西来广播所有语言控件都可以订阅的事件。

如果您不想使用这些框架,可以很容易地创建您自己的这种模式的实现。

【讨论】:

  • 使用 LanguageLabels 在加载时订阅的事件创建了我自己的解决方案。工作一种享受。