我正在尝试创建一个togglebutton,它会将应用程序主题更改为在按下时适合移动设备。这是一个特殊的皮肤,只会改变一些东西,如边距,字体大小和最小/宽度。这不应该删除我设置的其他样式。
我能够让按钮工作,但更改仅适用于当前窗口。如何更改此代码以使其适用于整个应用程序?
搜索我发现使用“Application.Current.Resources.MergedDictionaries”可能是要走的路,但我不知道如何合并它。
本网站的信息是基础。 http://svetoslavsavov.blogspot.com/2009/07/switching-wpf-interface-themes-at.html
以下是主题选择器的代码。
public class ThemeSelector : DependencyObject
{
public static readonly DependencyProperty CurrentThemeDictionaryProperty =
DependencyProperty.RegisterAttached("CurrentThemeDictionary", typeof(Uri),
typeof(ThemeSelector),
new UIPropertyMetadata(null, CurrentThemeDictionaryChanged));
public static Uri GetCurrentThemeDictionary(DependencyObject obj)
{
return (Uri)obj.GetValue(CurrentThemeDictionaryProperty);
}
public static void SetCurrentThemeDictionary(DependencyObject obj, Uri value)
{
obj.SetValue(CurrentThemeDictionaryProperty, value);
}
private static void CurrentThemeDictionaryChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
if (obj is FrameworkElement) // works only on FrameworkElement objects
{
ApplyTheme(obj as FrameworkElement, GetCurrentThemeDictionary(obj));
}
}
private static void ApplyTheme(FrameworkElement targetElement, Uri dictionaryUri)
{
if (targetElement == null) return;
try
{
ThemeResourceDictionary themeDictionary = null;
if (dictionaryUri != null)
{
themeDictionary = new ThemeResourceDictionary();
themeDictionary.Source = dictionaryUri;
// add the new dictionary to the collection of merged dictionaries of the target object
targetElement.Resources.MergedDictionaries.Insert(0, themeDictionary);
}
// find if the target element already has a theme applied
List<ThemeResourceDictionary> existingDictionaries =
(from dictionary in targetElement.Resources.MergedDictionaries.OfType<ThemeResourceDictionary>()
select dictionary).ToList();
// remove the existing dictionaries
foreach (ThemeResourceDictionary thDictionary in existingDictionaries)
{
if (themeDictionary == thDictionary) continue; // don't remove the newly added dictionary
targetElement.Resources.MergedDictionaries.Remove(thDictionary);
}
}
finally { }
}
}
以下是togglebutton代码隐藏的内容。
private void MobileTheme_Click(object sender, RoutedEventArgs e)
{
if ((sender as ToggleButton).IsChecked.Value)
{
ThemeSelector.SetCurrentThemeDictionary(this, new Uri("/MobileSkin.xaml", UriKind.Relative));
}
else
{
ThemeSelector.SetCurrentThemeDictionary(this, new Uri("/ClassicSkin.xaml", UriKind.Relative));
}
}
答案 0 :(得分:1)
有效的新代码:
public class ThemeSelector : DependencyObject
{
public static void ApplyTheme(Uri dictionaryUri)
{
var targetElement = Application.Current;
if (targetElement == null || dictionaryUri == null) return;
try
{
// find if the target element already has a theme applied
var existingDictionaries =
(from dictionary in targetElement.Resources.MergedDictionaries.OfType<ThemeResourceDictionary>()
select dictionary).ToList();
// remove the existing dictionaries
foreach (var thDictionary in existingDictionaries)
{
targetElement.Resources.MergedDictionaries.Remove(thDictionary);
}
// add the new dictionary to the collection of merged dictionaries of the target object, needs to be added to the end to overwrite the other items
targetElement.Resources.MergedDictionaries.Add(new ThemeResourceDictionary { Source = dictionaryUri });
}
finally { }
}
}
切换按钮:
private void MobileTheme_Click(object sender, RoutedEventArgs e)
{
if ((sender as ToggleButton)?.IsChecked.Value == true)
{
ThemeSelector.ApplyTheme(new Uri("/MobileSkin.xaml", UriKind.Relative));
}
else
{
ThemeSelector.ApplyTheme(new Uri("/ClassicSkin.xaml", UriKind.Relative));
}
}