代码之家  ›  专栏  ›  技术社区  ›  rfmodulator

如何在运行时更改WPF材质设计调色板?

  •  0
  • rfmodulator  · 技术社区  · 7 年前

    我最近“升级”了一个解决方案到VS2017和.NET Framework 4.6.1。

    我还将所有NuGet包更新为最新版本。

    MahApps.Metro by Jan Karger et al. 1.6.5 (1.3.0-ALPHA016)
    
    MaterialDesignColors by James Willock 1.1.3 (1.1.2)
    
    MaterialDesignThemes by James Willock 2.5.0.1205 (1.1.0.234)
    
    MaterialDesignThemes.MahApps by James Willock 0.0.12 (0.0.3)
    

    Extended.Wpf.Toolkit by Xceed 3.4.0 (2.6.0)
    
    ControlzEx by Jan Karger et al. 3.0.2.4 (none, new dependency of MahApps.Metro)
    

    private void primaryPaletteComboBox_SelectedIndexChanged(object sender, EventArgs e)
    {
       paletteHelper.ReplacePrimaryColor(this.primaryPaletteComboBox.Text);
    }
    
    /* Where: */
    
    var paletteHelper = new MaterialDesignThemes.Wpf.PaletteHelper();
    
    this.primaryPaletteComboBox.Items.AddRange(new object[] {
        "Amber",
        "Blue",
        "BlueGrey",
        "Brown",
        "Cyan",
        "DeepOrange",
        "DeepPurple",
        "Green",
        "Grey",
        "Indigo",
        "LightBlue",
        "LightGreen",
        "Lime",
        "Orange",
        "Pink",
        "Purple",
        "Red",
        "Teal",
        "Yellow"});
    

    更新之后, ReplacePrimaryColor 引发以下异常:

    System.InvalidOperationException:'无法安全确定单个 SecondaryAccentBrush的资源定义

    将这些包降级到以前的版本会导致其他问题。

    在这些包的最新版本中,如何在运行时更改调色板?

    很明显 SecondaryAccentBrush 是个问题。

    PaletteHelper现在提供 ReplacePalette(Palette palette) 方法,也许有一种方法可以通过使用预定义资源的名称来实例化调色板对象?

    我宁愿同时去看牙医和直肠科医生,也不愿在XAML资源定义上乱来。

    1 回复  |  直到 7 年前
        1
  •  5
  •   tinmac    6 年前

    可以使用MDIX PaletteHelper实现这一点。

    适用于深色/浅色

    在Ui&上放置一个切换按钮;将它的isChecked bool绑定到下面使用的isDark bool(绑定或代码隐藏,不管您如何连接ui)

        private readonly PaletteHelper _paletteHelper = new PaletteHelper();
        private void ToggleBaseColour(bool isDark)
        {
            ITheme theme = _paletteHelper.GetTheme();
            IBaseTheme baseTheme = isDark ? new MaterialDesignDarkTheme() : (IBaseTheme)new MaterialDesignLightTheme();
            theme.SetBaseTheme(baseTheme);
            _paletteHelper.SetTheme(theme);
        }
    

    主要和;强调色

    MDIX GitHub demo apps paletselector VM编写得很好&易于阅读的代码 here

        2
  •  2
  •   rfmodulator    7 年前

    这是我的工作,不是答案。

    因此,在启动时,默认调色板在App.xaml中设置:

    <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.SWATCHNAME.xaml" />
    

    Uri uri = new Uri($"pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.{SWATCHNAME}.xaml");
    System.Windows.Application.Current.Resources.MergedDictionaries.RemoveAt(4);
    System.Windows.Application.Current.Resources.MergedDictionaries.Insert(4, new ResourceDictionary() { Source = uri });
    

    Palette 建造师。

    唯一的另一个警告是只有一些元素在运行时被更改。在所有元素获得新颜色之前,必须使用AppStart.cs中的相同代码行重新启动应用程序。

    我希望这能帮助别人(注意SWATCHNAME占位符和特定的资源索引)

    如果有人有更好的主意,就告诉我。

        3
  •  0
  •   Michael280    7 年前

    这个问题很老了,但也许它能帮助别人。我认为您的xaml字典中缺少了一些条目(与重音颜色相关)。最小值应类似于以下内容

    <Application x:Class="MaterialTest.App"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 StartupUri="MainWindow.xaml">
        <Application.Resources>
            <ResourceDictionary>
                <ResourceDictionary.MergedDictionaries>
    
                    <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" />
                    <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
                    <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.DeepPurple.xaml" />
                    <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Lime.xaml" />
    
                </ResourceDictionary.MergedDictionaries>            
            </ResourceDictionary>
        </Application.Resources>
    </Application>
    

    请按此链接查找有关集成的更多信息: https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit/wiki/MahApps.Metro-integration

    SwatchesProvider swatchesProvider = new SwatchesProvider();
    List<string> PrimaryColorsList = swatchesProvider.Swatches.Select(a => a.Name).ToList();
    this.primaryPaletteComboBox.Items.AddRange(PrimaryColorsList);
    
    private void primaryPaletteComboBox_SelectedIndexChanged(object sender, EventArgs e)
    {
        SwatchesProvider swatchesProvider = new SwatchesProvider();
        Swatch color= swatchesProvider.Swatches.FirstOrDefault(a => a.Name == this.primaryPaletteComboBox.Text);
        paletteHelper.ReplacePrimaryColor(color);
    }
    
        4
  •  0
  •   janw arman aramesh    5 年前

    ITheme 有一个 SetPrimaryColor 和 SetSecondaryColor primaryLight , secondaryMid 一个主题的直接的和单独的。

    private readonly PaletteHelper _paletteHelper = new PaletteHelper();
    
    ITheme theme = _paletteHelper.GetTheme();
    theme.SetPrimaryColor(System.Windows.Media.Color.FromRgb(200, 0, 0)); //red
    _paletteHelper.SetTheme(theme);