Wpf 将控件样式与另一个项目动态设置的全局样式合并

Wpf 将控件样式与另一个项目动态设置的全局样式合并,wpf,xaml,binding,styles,Wpf,Xaml,Binding,Styles,我现在面临一个问题。我正在使用我在codeplex上找到的WPF.Themes,它允许我更改应用程序的主题 所以我导入了这个项目,并让它正常工作,但是对于一些控制,比如说我的treeViewItem,我已经为它设置了样式,它覆盖了全局样式 我有以下代码后,研究,但仍然不会工作 <TreeView Name="_tvTreeView" Grid.Row="1" > <TreeView.ItemContainerStyle> <Sty

我现在面临一个问题。我正在使用我在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中的主题,那么“BasedOn”将生效,但是如果我动态设置合并,那么“BasedOn”似乎不起作用

有没有一种方法可以让它在不向app.xaml添加主题的情况下工作


谢谢大家,

style的BaseOn属性不能使用DynamicResource设置,使用StaticResource,当应用于控件时,它将被密封

更改全局样式时,应合并样式,请尝试以下代码:

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>

<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>