简体   繁体   English

在WPF中创建UI设置的正确方法是什么?

[英]What is the proper way to create UI settings in WPF?

I'm working now on a base Style in XAML which includes a Template for my standard HandledWindow type. 我现在正在XAML中使用基本样式,其中包括用于我的标准HandledWindow类型的模板。 The style includes several local resources like colours, fonts and other variables to reuse later in my style. 该样式包括一些本地资源,例如颜色,字体和其他变量,这些样式稍后可以在我的样式中重复使用。

I was thinking of UI settings for the user, so he can change things like colours and sizes as he wishes. 我在考虑用户的UI设置,因此他可以根据需要更改颜色和大小等内容。 But then I've discovered that changing the local resource won't change the style itself but only for the current HandledWindow instance, So it's not suitable way for UI settings since there might be more then running window in the application. 但是后来我发现,更改本地资源不会更改样式本身,而只会更改当前的HandledWindow实例。因此,这不是UI设置的合适方法,因为应用程序中可能会有更多正在运行的窗口。

Then I realised I have to bind variables relatively to the template of my HandledWindow class, which will include all changeable settings as public & static properties. 然后我意识到我必须相对于HandledWindow类的模板绑定变量,该模板将包括所有可更改的设置作为公共和静态属性。 But then I encountered an issue with static property binding since I cannot raise the PropertyChanged event which works only for an instance. 但是后来我遇到了静态属性绑定的问题,因为我无法引发仅适用于实例的PropertyChanged事件。 And the window won't update it's style by itself. 而且窗口本身不会更新其样式。

In addition I am trying to make the style react and update immediately on the fly without restarts. 另外,我试图使样式做出反应并立即进行更新,而无需重新启动。

WPF is "resource-centric". WPF是“以资源为中心”的。 You define all your UI styles, brushes and templates in your resources and at runtime it is very easy to enable application-wide theme change that would encompass all the properties you mention. 您可以在资源中定义所有UI样式,画笔和模板,并且在运行时很容易启用包含您提到的所有属性的应用程序范围的主题更改。 Here is how I do it in my MainViewModel after it receives a message from my Settings Window via its SettingsViewModel: 这是我的MainViewModel通过它的SettingsViewModel从“设置”窗口接收到一条消息后在其内部执行的操作:

private void ApplyTheme()
{          
    Application.Current.Resources.MergedDictionaries.Clear();

    var rd = new ResourceDictionary { { "Locator", locator } };
    Application.Current.Resources.MergedDictionaries.Add(rd);

    switch (theme)
    {
        case "Blue":
            Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("/Telerik.Windows.Themes.Office_Blue;component/Themes/System.Windows.xaml", UriKind.RelativeOrAbsolute) });
            Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("/Telerik.Windows.Themes.Office_Blue;component/Themes/Telerik.Windows.Controls.GridView.xaml", UriKind.RelativeOrAbsolute) });
            Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("/Telerik.Windows.Themes.Office_Blue;component/Themes/Telerik.Windows.Controls.Input.xaml", UriKind.RelativeOrAbsolute) });
            Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("/Telerik.Windows.Themes.Office_Blue;component/Themes/Telerik.Windows.Controls.Navigation.xaml", UriKind.RelativeOrAbsolute) });
            Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("/Telerik.Windows.Themes.Office_Blue;component/Themes/Telerik.Windows.Controls.xaml", UriKind.RelativeOrAbsolute) });
            break;
        case "Summer":
            Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("/Telerik.Windows.Themes.Summer;component/Themes/System.Windows.xaml", UriKind.RelativeOrAbsolute) });
            Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("/Telerik.Windows.Themes.Summer;component/Themes/Telerik.Windows.Controls.GridView.xaml", UriKind.RelativeOrAbsolute) });
            Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("/Telerik.Windows.Themes.Summer;component/Themes/Telerik.Windows.Controls.Input.xaml", UriKind.RelativeOrAbsolute) });
            Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("/Telerik.Windows.Themes.Summer;component/Themes/Telerik.Windows.Controls.Navigation.xaml", UriKind.RelativeOrAbsolute) });
            Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("/Telerik.Windows.Themes.Summer;component/Themes/Telerik.Windows.Controls.xaml", UriKind.RelativeOrAbsolute) });
            break;
        }
        Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("Resources/Brushes.xaml", UriKind.RelativeOrAbsolute) });
        Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("Resources/ControlTemplates.xaml", UriKind.RelativeOrAbsolute) });
        Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("Resources/DataTemplates.xaml", UriKind.RelativeOrAbsolute) });
        Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("Resources/Styles.xaml", UriKind.RelativeOrAbsolute) });
    }

Obviously I am using Telerik controls so I load their dictionaries but at the bottom of the method you'll notice I load my own resources like Brushes, Styles etc. as well. 显然,我使用的是Telerik控件,因此我加载了它们的字典,但是在方法的底部,您会注意到我也加载了我自己的资源,例如Br​​ushes,Styles等。

In conclusion, application-wide theme changes could not be easier with WPF. 总之,使用WPF不会更容易在应用程序范围内更改主题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM