-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix for Dialogs crash when app style is set via ThemeManager #1358 #1383
Conversation
I cannot see any relevant error messages on the build. What is wrong? |
The CI needs to build it again because the first time, it restored the nuget packages.
cc @MahApps/contributors |
@Amrykid Ignore the CI, that was just a test of mine and it somehow automatically added notifications to Github |
Cool, then I hope you can accept this pull request asap. I have committed my customized assemblies to source control, but NuGet keeps "restoring" them ;-) |
Fix for Dialogs crash when app style is set via ThemeManager #1358
- this change brakes the thememanger's default usage - handle not finding app style
revert thememanager changes from #1383
@GeertvanHorrik i must revert your pr, sorry for this... but it breaks the default thememanager usage. to handle custom accents or themes you must follow thes rules:
short example (you can look into my simple mahapps demo to see how it works) <Application x:Class="MahApps.Metro.Simple.Demo.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:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
<ResourceDictionary Source="/Resources/Icons.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro.Simple.Demo;component/CustomAccents/CustomAccent1.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application> public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
ThemeManager.AddAccent("CustomAccent1", new Uri("pack://application:,,,/MahApps.Metro.Simple.Demo;component/CustomAccents/CustomAccent1.xaml"));
ThemeManager.AddAccent("CustomAccent2", new Uri("pack://application:,,,/MahApps.Metro.Simple.Demo;component/CustomAccents/CustomAccent2.xaml"));
ThemeManager.AddAppTheme("CustomTheme", new Uri("pack://application:,,,/MahApps.Metro.Simple.Demo;component/CustomAccents/CustomTheme.xaml"));
base.OnStartup(e);
}
} private void CustomThemeAppButtonClick(object sender, RoutedEventArgs e)
{
var theme = ThemeManager.DetectAppStyle(Application.Current);
ThemeManager.ChangeAppStyle(Application.Current, theme.Item2, ThemeManager.GetAppTheme("CustomTheme"));
}
private void CustomAccent1AppButtonClick(object sender, RoutedEventArgs e)
{
var theme = ThemeManager.DetectAppStyle(Application.Current);
ThemeManager.ChangeAppStyle(Application.Current, ThemeManager.GetAccent("CustomAccent1"), theme.Item1);
}
private void CustomAccent2AppButtonClick(object sender, RoutedEventArgs e)
{
var theme = ThemeManager.DetectAppStyle(Application.Current);
ThemeManager.ChangeAppStyle(Application.Current, ThemeManager.GetAccent("CustomAccent2"), theme.Item1);
} |
The problem is that you check by Source (which is not available on runtime dictionaries). I have the ability to create dynamic accents based on a single color (because that is all you need). Can you tell me what it breaks? I explicitly added the check at the end to allow the MahApps logic to always be first. |
If you tell me what gets broken, I can fix that. I think it's not good to require a resource uri (because all you really need is a resource dictionary, not some sort of fixed uri). |
@GeertvanHorrik look at the main mahapps demo and change the accent (through the menu) with your changes. you will see that nothing happens. the detection gets always your created accent. |
@GeertvanHorrik maybe we need another additional feature to allow adding runtime res dict (-> Orchestra) |
I will check out your demo and see if I can come up with a full working solution. We would love the code in Orchestra to be contributed to MahApps (I think more people want to be able to set the accent color based on a single color). Let me know if you are interested in that. |
@GeertvanHorrik i updated my example with this solution (maybe not the best, but it works) public static void SetThemeColor(Color color, bool changeImmediately = false)
{
//Log.Info("Setting theme to '{0}'", color.ToString());
//<Color x:Key="HighlightColor">
// #800080
//</Color>
//<Color x:Key="AccentColor">
// #CC800080
//</Color>
//<Color x:Key="AccentColor2">
// #99800080
//</Color>
//<Color x:Key="AccentColor3">
// #66800080
//</Color>
//<Color x:Key="AccentColor4">
// #33800080
//</Color>
//<SolidColorBrush x:Key="HighlightBrush" Color="{StaticResource HighlightColor}" />
//<SolidColorBrush x:Key="AccentColorBrush" Color="{StaticResource AccentColor}" />
//<SolidColorBrush x:Key="AccentColorBrush2" Color="{StaticResource AccentColor2}" />
//<SolidColorBrush x:Key="AccentColorBrush3" Color="{StaticResource AccentColor3}" />
//<SolidColorBrush x:Key="AccentColorBrush4" Color="{StaticResource AccentColor4}" />
//<SolidColorBrush x:Key="WindowTitleColorBrush" Color="{StaticResource AccentColor}" />
//<SolidColorBrush x:Key="AccentSelectedColorBrush" Color="White" />
//<LinearGradientBrush x:Key="ProgressBrush" EndPoint="0.001,0.5" StartPoint="1.002,0.5">
// <GradientStop Color="{StaticResource HighlightColor}" Offset="0" />
// <GradientStop Color="{StaticResource AccentColor3}" Offset="1" />
//</LinearGradientBrush>
//<SolidColorBrush x:Key="CheckmarkFill" Color="{StaticResource AccentColor}" />
//<SolidColorBrush x:Key="RightArrowFill" Color="{StaticResource AccentColor}" />
//<Color x:Key="IdealForegroundColor">
// Black
//</Color>
//<SolidColorBrush x:Key="IdealForegroundColorBrush" Color="{StaticResource IdealForegroundColor}" />
//Log.Debug("Creating 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("AccentSelectedColorBrush", new SolidColorBrush(Colors.White));
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.Black);
resourceDictionary.Add("IdealForegroundColorBrush", new SolidColorBrush((Color)resourceDictionary["IdealForegroundColor"]));
var application = Application.Current;
var applicationTheme = ThemeManager.AppThemes.First(x => string.Equals(x.Name, "BaseLight"));
//Log.Debug("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)
{
ThemeManager.ChangeAppStyle(application, newAccent, applicationTheme);
}
} |
Ok, I can imagine why you do that, but not deleting temp files can hurt your at one point (but ok, this isn't a lot of files :-)). For now I will use this example, thanks for updating it. I think you should still consider adding something like this to MahApps! Great work 👍 |
It still looks to crash when I show a message box / dialog. |
Sorry for my late reply, was side-tracked. Now looking into a definitive fix. |
Found the bug! There were 2 issues:
|
MOD EDIT:
Fixes #1385
Fixes #1358
MOD EDIT by @Amrykid