如何在运行时更改WPF Material Design Palette?

问题描述 投票:0回答:2

我最近“升级”了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)

WPF相关软件包也被引用包括:

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)

在更新之前,以下内容将在运行时更改UI调色板:

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的单个资源定义。

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

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

我想通过简单地使用用户从ComboBox中选择的调色板名称来实现这一点。

显然SecondaryAccentBrush是一个问题。

有谁知道最近几年发生了什么变化?

这应该很简单,但谷歌并没有给我任何有用的东西。也许我不是在问正确的问题。

PaletteHelper现在提供了一个看起来很有希望的ReplacePalette(Palette palette)方法,也许有一种方法可以通过使用预定义资源的名称来实例化Palette对象?

我宁愿同时去看牙医和直肠科医生,也不愿意使用XAML资源定义。

c# wpf mahapps.metro material-design-in-xaml
2个回答
0
投票

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

所以在启动时,默认调色板在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构造函数中指定重音或设置Hue索引。

有问题的资源总是在索引4处,所以现在我正在使用它,因为App.xaml中没有定义任何键。

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

我希望这有助于其他人。 (注意SWATCHNAME占位符和您的特定资源索引)

如果有人有更好的想法,请把它放在我身上。


0
投票

问题很老但也许会帮助别人。我想你在xaml词典中缺少一些条目(与Accent颜色有关)。最小值应类似于以下内容

<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>

但在你的情况下,这还不够。您正在与MahApp.Metro集成请按照此链接查找有关集成的更多信息: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);
}
© www.soinside.com 2019 - 2024. All rights reserved.