繁体   English   中英

动态更改主题 Telerik WPF

[英]Change Theme Dynamically Telerik WPF

我需要允许用户在使用 telerik WPF 控件创建的应用程序中动态更改主题。

我正在为我的 XAML 中的每个 telerik 控件设置绑定,如下所示:

XAML:

telerik:StyleManager.Theme="{Binding SelectedSMTheme, Mode=TwoWay}"

视图模型:

    private Theme selectedSMTheme;
    public Theme SelectedSMTheme
    {
        get
        {
            return selectedSMTheme;
        }
        set
        {
            selectedSMTheme = value;
            RaisePropertyChange("SelectedSMTheme");
        }
    }

并在用户 select 主题时更改此SelectedSMTheme

改变主题:

SelectedSMTheme = new Expression_DarkTheme();

在运行应用程序时是否有任何其他方法可以更改 telerik 控件的主题。 因为,在这里我需要为整个应用程序中的每个控件指定telerik:StyleManager.Theme

您可以使用StyleManager.ApplicationTheme来设置初始主题。 设置此属性会影响应用程序中的所有控件。

您的 App.xaml.cs 构造函数应如下所示:

public partial class App : Application
{
    public App()
    {
        StyleManager.ApplicationTheme = new Expression_DarkTheme();
        this.InitializeComponent();
    }
}

要在运行时切换主题,您应该清除应用程序资源并添加新资源。

private void btnChangeTheme_Click(object sender, RoutedEventArgs e)
{
    Application.Current.Resources.MergedDictionaries.Clear();
    Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary()
    {
        Source = new Uri("/Telerik.Windows.Themes.Green;component/Themes/System.Windows.xaml", UriKind.RelativeOrAbsolute)
    });
    Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary()
    {
        Source = new Uri("/Telerik.Windows.Themes.Green;component/Themes/Telerik.Windows.Controls.xaml", UriKind.RelativeOrAbsolute)
    });
    Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary()
    {
        Source = new Uri("/Telerik.Windows.Themes.Green;component/Themes/Telerik.Windows.Controls.Input.xaml", UriKind.RelativeOrAbsolute)
    });
}

您必须记住从位于安装文件夹中的 Binaries.NoXaml 文件夹中添加所需的程序集(在我的例子中是: C:\\Program Files (x86)\\Progress\\Telerik UI for WPF R2 2018\\Binaries.NoXaml ):

  • Telerik.Windows.Controls.dll
  • Telerik.Windows.Controls.Input.dll
  • 主题程序集,在我的情况下是: Telerik.Windows.Themes.Expression_Dark.dllTelerik.Windows.Themes.Green.dll

请阅读以下文章以获取更多信息:

https://docs.telerik.com/devtools/wpf/styling-and-appearance/stylemanager/common-styling-apperance-setting-theme-wpf

https://docs.telerik.com/devtools/wpf/styling-and-appearance/how-to/styling-apperance-themes-runtime

我正在使用与 kmatyaszek 提供的类似解决方案,除了我在 ComboBox 中执行此操作:

 private void StyleCombo_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        var selectedTheme = StyleCombo.SelectedItem as ThemeNames;
        Application.Current.Resources.MergedDictionaries.Clear();

        // XAML

        Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary
        {
            Source = new Uri("/Telerik.Windows.Themes." + selectedTheme.Value + ";component/Themes/System.Windows.xaml", UriKind.RelativeOrAbsolute)
        });
        Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary
        {
            Source = new Uri("/Telerik.Windows.Themes." + selectedTheme.Value + ";component/Themes/Telerik.Windows.Controls.xaml", UriKind.RelativeOrAbsolute)
        });
        Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary
        {
            Source = new Uri("/Telerik.Windows.Themes." + selectedTheme.Value + ";component/Themes/Telerik.Windows.Controls.Input.xaml", UriKind.RelativeOrAbsolute)
        });
        Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary
        {
            Source = new Uri("/Telerik.Windows.Themes." + selectedTheme.Value + ";component/Themes/Telerik.Windows.Controls.Navigation.xaml", UriKind.RelativeOrAbsolute)
        });
        Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary
        {
            Source = new Uri("/Telerik.Windows.Themes." + selectedTheme.Value + ";component/Themes/Telerik.Windows.Controls.Data.xaml", UriKind.RelativeOrAbsolute)
        });
        Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary
        {
            Source = new Uri("/Telerik.Windows.Themes." + selectedTheme.Value + ";component/Themes/Telerik.Windows.Controls.DataVisualization.xaml", UriKind.RelativeOrAbsolute)
        });
        Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary
        {
            Source = new Uri("/Telerik.Windows.Themes." + selectedTheme.Value + ";component/Themes/Telerik.Windows.Controls.Docking.xaml", UriKind.RelativeOrAbsolute)
        });
        Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary
        {
            Source = new Uri("/Telerik.Windows.Themes." + selectedTheme.Value + ";component/Themes/Telerik.Windows.Controls.GridView.xaml", UriKind.RelativeOrAbsolute)
        });
        Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary
        {
            Source = new Uri("/Telerik.Windows.Themes." + selectedTheme.Value + ";component/Themes/Telerik.Windows.Controls.Pivot.xaml", UriKind.RelativeOrAbsolute)
        });
        Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary
        {
            Source = new Uri("/Telerik.Windows.Themes." + selectedTheme.Value + ";component/Themes/Telerik.Windows.Controls.PivotFieldList.xaml", UriKind.RelativeOrAbsolute)
        });
        Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary
        {
            Source = new Uri("/Telerik.Windows.Themes." + selectedTheme.Value + ";component/Themes/Telerik.Windows.Controls.VirtualGrid.xaml", UriKind.RelativeOrAbsolute)
        });
}

您在评论部分说过,某些控件不会动态更改 - 这是 NoXaml 库的已知问题。 我可以向您推荐的是手动设置这些控件的参数。 就我而言,它看起来像这样:

// Main Grid

        if (selectedTheme.Name == "Visual Studio 2013 Dark")
        {
            VisualStudio2013Palette.LoadPreset(VisualStudio2013Palette.ColorVariation.Dark);
            App.StronaGlowna.MainGrid.Background = (SolidColorBrush)new BrushConverter().ConvertFrom("#FF1E1E1E");
        }

        if (selectedTheme.Name == "Visual Studio 2013 Blue")
        {
            VisualStudio2013Palette.LoadPreset(VisualStudio2013Palette.ColorVariation.Blue);
        }

        if (selectedTheme.Name == "Visual Studio 2013")
        {
            VisualStudio2013Palette.LoadPreset(VisualStudio2013Palette.ColorVariation.Light);
            App.StronaGlowna.MainGrid.Background = Brushes.White;
        }



        if (selectedTheme.Name == "Dark")
        {
            VisualStudio2013Palette.LoadPreset(VisualStudio2013Palette.ColorVariation.Dark);
            App.StronaGlowna.MainGrid.Background = (SolidColorBrush)new BrushConverter().ConvertFrom("#FF3D3D3D");
        }

        if (selectedTheme.Name == "Green")
        {
            GreenPalette.LoadPreset(GreenPalette.ColorVariation.Dark);
            App.StronaGlowna.MainGrid.Background = (SolidColorBrush)new BrushConverter().ConvertFrom("#FF1D1E21");
        }

        if (selectedTheme.Name == "Green Light")
        {
            GreenPalette.LoadPreset(GreenPalette.ColorVariation.Light);
            App.StronaGlowna.MainGrid.Background = (SolidColorBrush)new BrushConverter().ConvertFrom("#FFE0E0E0");
        }

        if (selectedTheme.Name == "Vista" ||
            selectedTheme.Name == "Visual Studio 2013 Blue" || selectedTheme.Name == "Office Black" ||
            selectedTheme.Name == "Office Blue" ||
            selectedTheme.Name == "Office Silver" || selectedTheme.Name == "Summer" ||
            selectedTheme.Name == "Transparent" || selectedTheme.Name == "Windows 7")
        {
            App.StronaGlowna.MainGrid.Background = Brushes.White;
        }

这个解决方案是由 Telerik 支持在 1 个支持票中提供给我的。 您可以在文档中找到大多数控件的十六进制颜色,例如这个是针对 Office2013 主题的 另外,请记住,某些 WPF 控件不受样式的影响(我认为其中一个示例是 TextBox),因此如果您使用的是 vanilla WPF 控件,它们可能保持不变并需要您对新颜色进行硬编码。

相同但更好,从可用的主题 dll 动态加载并适用于任何使用的库(尝试 {} catch)

    void LoadThemeNames()
    {
        var directory = AppDomain.CurrentDomain.BaseDirectory;
        var files = Directory.GetFiles(directory, "Telerik.Windows.Themes.*.dll");

        foreach (var item in files)
        {
            var name = item.Split('.')[3];
            ThemeCombo.Items.Add(new RadComboBoxItem() { Content = name.Replace("_", " "), Name = name });   
        }
    }


    public void ChangeTheme(string selectedTheme)
    {
        Application.Current.Resources.MergedDictionaries.Clear();

        string[] lst = new string[] {
            "System.Windows.xaml",
            "Telerik.Windows.Controls.xaml",
            "Telerik.Windows.Controls.Input.xaml",
            "Telerik.Windows.Controls.Navigation.xaml",
            "Telerik.Windows.Controls.Data.xaml",
            "Telerik.Windows.Controls.DataVisualization.xaml",
            "Telerik.Windows.Controls.Docking.xaml",
            "Telerik.Windows.Controls.GridView.xaml",
            "Telerik.Windows.Controls.Pivot.xaml",
            "Telerik.Windows.Controls.PivotFieldList.xaml",
            "Telerik.Windows.Controls.VirtualGrid.xaml"};

        foreach (var item in lst)
        {
            var uri = new Uri("/Telerik.Windows.Themes." + selectedTheme + ";component/Themes/" + item, UriKind.RelativeOrAbsolute);

            if (uri != null)
            {
                try
                {
                    var rsc = new ResourceDictionary { Source = uri };
                    Application.Current.Resources.MergedDictionaries.Add(rsc);
                }
                catch (Exception e) { }
            }
        }
    }

    private void RadComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        ChangeTheme(((RadComboBoxItem)ThemeCombo.SelectedItem).Name.ToString());
    }

暂无
暂无

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

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