2011-03-07 58 views
0

我目前正面臨一個問題。我使用的是WPF.Themes,我在codeplex上找到它,它允許我改變我的應用程序的主題。將控件樣式與由另一個項目動態設置的全局樣式合併

所以我導入項目,並得到它一切工作正常,但對於一些控制,說我的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」將啓動並工作,但如果我動態設置mergedictionaries,「BasedOn」似乎不起作用。

有沒有一種方法可以在不添加主題到app.xaml的情況下工作。

感謝和問候,

回答

1

的風格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>