Как создать акцентный ресурс MahApps.Metro из определенного цвета?

Я заметил это на сайте MahApps (внизу страницы): "Это также можно динамически создавать словарь ресурсов акцента, используя определенный цвет.», но больше я нигде не нашел.

Действительно ли существует встроенный метод (или что-то еще) для этого?
Я нашел только ThemeManager.AddAccent(string name, Uri resourceAddress), а создание нового акцента (в настоящее время) возможно с помощью new Accent(string name, Uri resourceAddress), поэтому имя и ресурс uri необходимы во всех случаях. ..
Есть идеи?


person nvi9    schedule 21.09.2015    source источник


Ответы (2)


Вот простой пример создания динамического словаря ресурсов и добавления его в ThemeManager:

public static class ThemeManagerHelper
{
    public static void CreateAppStyleBy(Color color, bool changeImmediately = false)
    {
        // create a runtime accent resource dictionary

        var resourceDictionary = new ResourceDictionary();

        resourceDictionary.Add("HighlightColor", color);
        resourceDictionary.Add("AccentColor", Color.FromArgb((byte)(204), color.R, color.G, color.B));
        resourceDictionary.Add("AccentColor2", Color.FromArgb((byte)(153), color.R, color.G, color.B));
        resourceDictionary.Add("AccentColor3", Color.FromArgb((byte)(102), color.R, color.G, color.B));
        resourceDictionary.Add("AccentColor4", Color.FromArgb((byte)(51), color.R, color.G, color.B));

        resourceDictionary.Add("HighlightBrush", new SolidColorBrush((Color)resourceDictionary["HighlightColor"]));
        resourceDictionary.Add("AccentColorBrush", new SolidColorBrush((Color)resourceDictionary["AccentColor"]));
        resourceDictionary.Add("AccentColorBrush2", new SolidColorBrush((Color)resourceDictionary["AccentColor2"]));
        resourceDictionary.Add("AccentColorBrush3", new SolidColorBrush((Color)resourceDictionary["AccentColor3"]));
        resourceDictionary.Add("AccentColorBrush4", new SolidColorBrush((Color)resourceDictionary["AccentColor4"]));
        resourceDictionary.Add("WindowTitleColorBrush", new SolidColorBrush((Color)resourceDictionary["AccentColor"]));

        resourceDictionary.Add("ProgressBrush", new LinearGradientBrush(
            new GradientStopCollection(new[]
            {
                new GradientStop((Color)resourceDictionary["HighlightColor"], 0),
                new GradientStop((Color)resourceDictionary["AccentColor3"], 1)
            }),
            new Point(0.001, 0.5), new Point(1.002, 0.5)));

        resourceDictionary.Add("CheckmarkFill", new SolidColorBrush((Color)resourceDictionary["AccentColor"]));
        resourceDictionary.Add("RightArrowFill", new SolidColorBrush((Color)resourceDictionary["AccentColor"]));

        resourceDictionary.Add("IdealForegroundColor", Colors.White);
        resourceDictionary.Add("IdealForegroundColorBrush", new SolidColorBrush((Color)resourceDictionary["IdealForegroundColor"]));
        resourceDictionary.Add("AccentSelectedColorBrush", new SolidColorBrush((Color)resourceDictionary["IdealForegroundColor"]));

        // DataGrid brushes since latest alpha after 1.1.2
        resourceDictionary.Add("MetroDataGrid.HighlightBrush", new SolidColorBrush((Color)resourceDictionary["AccentColor"]));
        resourceDictionary.Add("MetroDataGrid.HighlightTextBrush", new SolidColorBrush((Color)resourceDictionary["IdealForegroundColor"]));
        resourceDictionary.Add("MetroDataGrid.MouseOverHighlightBrush", new SolidColorBrush((Color)resourceDictionary["AccentColor3"]));
        resourceDictionary.Add("MetroDataGrid.FocusBorderBrush", new SolidColorBrush((Color)resourceDictionary["AccentColor"]));
        resourceDictionary.Add("MetroDataGrid.InactiveSelectionHighlightBrush", new SolidColorBrush((Color)resourceDictionary["AccentColor2"]));
        resourceDictionary.Add("MetroDataGrid.InactiveSelectionHighlightTextBrush", new SolidColorBrush((Color)resourceDictionary["IdealForegroundColor"]));

        // applying theme to MahApps

        var resDictName = string.Format("ApplicationAccent_{0}.xaml", color.ToString().Replace("#", string.Empty));
        var fileName = Path.Combine(Path.GetTempPath(), resDictName);
        using (var writer = System.Xml.XmlWriter.Create(fileName, new System.Xml.XmlWriterSettings { Indent = true }))
        {
            System.Windows.Markup.XamlWriter.Save(resourceDictionary, writer);
            writer.Close();
        }

        resourceDictionary = new ResourceDictionary() { Source = new Uri(fileName, UriKind.Absolute) };

        var newAccent = new Accent { Name = resDictName, Resources = resourceDictionary };
        ThemeManager.AddAccent(newAccent.Name, newAccent.Resources.Source);

        if (changeImmediately)
        {
            var application = Application.Current;
            var applicationTheme = ThemeManager.AppThemes.First(x => string.Equals(x.Name, "BaseLight"));
            ThemeManager.ChangeAppStyle(application, newAccent, applicationTheme);
        }
    }
}

Применение:

ThemeManagerHelper.CreateAppStyleBy(Colors.Indigo, true);

Это взято из моих примеров кода (MahAppsMetroThemesSample), размещенных на GitHub.

Надеюсь это поможет!

person punker76    schedule 21.09.2015
comment
Вау, это восхитительно, спасибо большое!!! Просто предложение: для IdealForegroundColor цвет можно создать и программно, исходя из яркости параметра color, вот так: resourceDictionary.Add("IdealForegroundColor", (int)Math.Sqrt(color.R * color.R * .241 + color.G * color.G * .691 + color.B * color.B * .068) < 130 ? Colors.White : Colors.Black); (источник) - person nvi9; 22.09.2015

С тех пор ThemeManager был изменен и теперь изначально поддерживает создание пользовательской темы из цвета.

Вот пример из документации MahApps:

// Add Dark and Light versions of DarkRed
ThemeManager.Current.AddTheme(new Theme("CustomDarkRed", "CustomDarkRed", "Dark", "Red", Colors.DarkRed, Brushes.DarkRed, true, false));
ThemeManager.Current.AddTheme(new Theme("CustomLightRed", "CustomLightRed", "Light", "Red", Colors.DarkRed, Brushes.DarkRed, true, false));

//Set current theme to CustomDarkRed
ThemeManager.Current.ChangeTheme(this, "CustomDarkRed");
person DaemonFire    schedule 09.03.2021