Как изменить палитру материалов WPF во время выполнения? - PullRequest
0 голосов
/ 27 января 2019

Я недавно "обновил" решение до 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)

До обновления,следующее изменило бы цветовую палитру пользовательского интерфейса во время выполнения:

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 является проблемой.

Кто-нибудь знает, что изменилось за последние несколько лет?

Это должно быть легко, но Google не дает мне ничего полезного.Может быть, я не задаю правильный вопрос.

PaletteHelper теперь предоставляет метод ReplacePalette(Palette palette), который выглядит многообещающе, возможно, есть способ создать экземпляр объекта Palette, используя имя предопределенного ресурса?

Я бы предпочел пойти к стоматологу и проктологу одновременно, чем разбираться с определениями ресурсов XAML.

Ответы [ 2 ]

0 голосов
/ 11 марта 2019

Вопрос довольно старый, но, возможно, он поможет кому-то еще.Я думаю, что вам не хватает некоторых записей в словаре 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);
}
0 голосов
/ 29 января 2019

Это моя работа, это не ответ.

Итак, при запуске в 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Конструктор.

Рассматриваемый ресурс всегда имеет индекс 4, поэтому сейчас я использую его, так как ключи в App.xaml не определены.

Единственное другое предостережение - только некоторыеэлементы меняются во время выполнения.Приложение должно быть перезапущено, прежде чем все элементы получат новые цвета, используя те же строки кода в AppStart.cs.

Надеюсь, это поможет кому-то еще.(обратите внимание на местозаполнитель SWATCHNAME и индекс вашего ресурса)

Если у кого-то есть идея получше, напишите мне.

...