我目前正面临一个问题。我正在使用我在codeplex上找到的WPF.Themes,它允许我改变我的应用程序的主题。
所以我导入了这个项目并且一切正常,但是对于某些控件,比如我的treeViewItem,我已经设置了它的样式,它覆盖了全局样式。
我在研究后得到以下代码,但仍然无效。
<TreeView Name="_tvTreeView" Grid.Row="1" >
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}" BasedOn="{StaticResource {x:Type TreeViewItem}}">
<EventSetter Event="MouseDoubleClick" Handler="tvTreeView_PreviewMouseDoubleClick"/>
<EventSetter Event="MouseDown" Handler="tvTreeView_MouseDown"/>
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
如果我在我的主项目的app.xaml的合并字典中手动添加resrouce文件,那么基于工作原理。
但WPF.Themes项目允许我动态更改主题。
public static void ApplyTheme(this ContentControl control, string theme)
{
ResourceDictionary dictionary = ThemeManager.GetThemeResourceDictionary(theme);
control.Resources.MergedDictionaries.Clear();
if (dictionary != null)
control.Resources.MergedDictionaries.Add(dictionary);
}
拥有上述代码,不会合并全局样式和我的事件设置器。 如果我在app.xaml中手动引用主题,那么“BasedOn”将启动并运行,但如果我动态设置mergedDictionaries,“BasedOn”似乎不起作用。
如果没有将主题添加到app.xaml,我有没有办法让它工作。
谢谢和问候,
答案 0 :(得分:1)
使用DynamicResource无法使用DynamicResource设置样式的BaseOn属性,在应用于控件时它将被密封。
您应该在全局样式更改时合并样式,请尝试以下代码:
public class Behavior
{
#region AutoMergeStyle
public static readonly DependencyProperty AutoMergeStyleProperty =
DependencyProperty.RegisterAttached("AutoMergeStyle", typeof(bool), typeof(Behavior),
new FrameworkPropertyMetadata((bool)false,
new PropertyChangedCallback(OnAutoMergeStyleChanged)));
public static bool GetAutoMergeStyle(DependencyObject d)
{
return (bool)d.GetValue(AutoMergeStyleProperty);
}
public static void SetAutoMergeStyle(DependencyObject d, bool value)
{
d.SetValue(AutoMergeStyleProperty, value);
}
private static void OnAutoMergeStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (e.OldValue == e.NewValue)
{
return;
}
Control control = d as Control;
if (control == null)
{
throw new NotSupportedException("AutoMergeStyle can only used in Control");
}
if ((bool)e.NewValue)
{
Type type = d.GetType();
control.SetResourceReference(Behavior.BaseOnStyleProperty, type);
}
else
{
control.ClearValue(Behavior.BaseOnStyleProperty);
}
}
#endregion
#region BaseOnStyle
public static readonly DependencyProperty BaseOnStyleProperty =
DependencyProperty.RegisterAttached("BaseOnStyle", typeof(Style), typeof(Behavior),
new FrameworkPropertyMetadata((Style)null,
new PropertyChangedCallback(OnBaseOnStyleChanged)));
public static Style GetBaseOnStyle(DependencyObject d)
{
return (Style)d.GetValue(BaseOnStyleProperty);
}
public static void SetBaseOnStyle(DependencyObject d, Style value)
{
d.SetValue(BaseOnStyleProperty, value);
}
private static void OnBaseOnStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (e.OldValue == e.NewValue)
{
return;
}
Control control = d as Control;
if (control == null)
{
throw new NotSupportedException("BaseOnStyle can only used in Control");
}
Style baseOnStyle = e.NewValue as Style;
Style originalStyle = GetOriginalStyle(control);
if (originalStyle == null)
{
originalStyle = control.Style;
SetOriginalStyle(control, originalStyle);
}
Style newStyle = originalStyle;
if (originalStyle.IsSealed)
{
newStyle = new Style();
newStyle.TargetType = originalStyle.TargetType;
//1. Copy resources, setters, triggers
newStyle.Resources = originalStyle.Resources;
foreach (var st in originalStyle.Setters)
{
newStyle.Setters.Add(st);
}
foreach (var tg in originalStyle.Triggers)
{
newStyle.Triggers.Add(tg);
}
//2. Set BaseOn Style
newStyle.BasedOn = baseOnStyle;
}
else
{
originalStyle.BasedOn = baseOnStyle;
}
control.Style = newStyle;
}
#endregion
#region OriginalStyle
public static readonly DependencyProperty OriginalStyleProperty =
DependencyProperty.RegisterAttached("OriginalStyle", typeof(Style), typeof(Behavior),
new FrameworkPropertyMetadata((Style)null));
public static Style GetOriginalStyle(DependencyObject d)
{
return (Style)d.GetValue(OriginalStyleProperty);
}
public static void SetOriginalStyle(DependencyObject d, Style value)
{
d.SetValue(OriginalStyleProperty, value);
}
#endregion
}
将附加属性AutoMergeStyle添加到xaml:
<Style TargetType="{x:Type TreeViewItem}" BasedOn="{StaticResource {x:Type TreeViewItem}}">
<EventSetter Event="MouseDoubleClick" Handler="tvTreeView_PreviewMouseDoubleClick"/>
<EventSetter Event="MouseDown" Handler="tvTreeView_MouseDown"/>
<Setter Property="Behavior.AutoMergeStyle" Property="True"/>
</Style>