2011-07-20 49 views
8

有一個WPF用戶控件庫,並在其中兩個(或更多)用戶控制。我需要在兩個用戶控件中使用相同的樣式。我怎樣才能分享這種風格? 例如:在WPF用戶控件庫中的UserControl之間共享資源的最簡單方法是什麼?

這是風格:

<Style x:Key="customLabelStyle" TargetType="Label"> 
    ... 
</Style> 

用戶控件:

<UserControl x:Class="Edu.Wpf.Example.UserControlA" 
    ...xmlns stuff... > 
    <Grid> 
     ... some xaml markup... 
     <Label Style="{StaticResource customLabelStyle}"/> 
    </Grid> 
</UserControl> 

用戶控件B:

<UserControl x:Class="Edu.Wpf.Example.UserControlB" 
    ...xmlns stuff... > 
    <Grid> 
     ... some another xaml markup... 
     <Label Style="{StaticResource customLabelStyle}"/> 
    </Grid> 
</UserControl> 

因此,如何能我共享用戶之間這種風格不涉及應用程序app.xaml資源字典的庫中的控件?

UPDATE

我可以添加主題\ Generic.xaml到我的圖書館和定義樣式出現。但在這種情況下,我必須使用ComponentResourceKey作爲樣式的關鍵。對?它很長很不方便...

回答

2

您可以在單獨的ResourceDictionary中定義共享資源,然後使用MergedDictionaries將它們合併到您的UserControl的資源中。

12

說,你有一個資源定義顏色,就像這樣:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <Color A="#FF" R="#FF" G="#22" B="#11" x:Key="MyRed"/> 
    <Color A="#FF" R="#00" G="#FF" B="#21" x:Key="MyGreen"/> 
    <Color A="#FF" R="#00" G="#22" B="#FF" x:Key="MyBlue" /> 


    <SolidColorBrush x:Key="MyGreenBrush" Color="{StaticResource MyGreen}"/> 
    <SolidColorBrush x:Key="MyRedBrush" Color="{StaticResource MyRed}"/> 
    <SolidColorBrush x:Key="MyBlueBrush" Color="{StaticResource MyBlue}"/> 
</ResourceDictionary> 

而另一個定義是這樣一些基本樣式:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <Style TargetType="{x:Type TextBlock}" x:Key="PocTextBlock"> 
     <Setter Property="FontSize" Value="16"/> 
    </Style> 

    <Style TargetType="{x:Type TextBox}" x:Key="MyTextBox"> 
     <Setter Property="FontSize" Value="20"/> 
     <Setter Property="Foreground" Value="{DynamicResource MyGreenBrush}"/> 
    </Style> 

    <Style TargetType="{x:Type TextBlock}" x:Key="MyResultTextBlock"> 
     <Setter Property="FontSize" Value="16"/> 
     <Setter Property="FontWeight" Value="Bold"/> 
     <Setter Property="Foreground" Value="{DynamicResource MyGreenBrush}"/> 
    </Style> 

    <Style TargetType="{x:Type Border}" x:Key="MyBorder"> 
     <Setter Property="BorderBrush" Value="{DynamicResource MyGreenBrush}"/> 
     <Setter Property="BorderThickness" Value="4"/> 
     <Setter Property="CornerRadius" Value="5"/> 
    </Style> 
</ResourceDictionary> 

然後,您可以添加自己的資源的應用程序。 XAML的Application.Resources標籤,如下所示:

<Application.Resources> 
     <ResourceDictionary> 
      <ResourceDictionary.MergedDictionaries> 
       <ResourceDictionary Source="OtherStyles.xaml"/> 
       <ResourceDictionary Source="Colors.xaml"/> 
      </ResourceDictionary.MergedDictionaries> 
     </ResourceDictionary> 
    </Application.Resources> 
</Application> 

然後,在你所有的用戶控件,你可以使用樣式或畫筆作爲示例代碼顯示的StaticResources。

+3

這是一個插件庫。所以我不能使用App.xaml。 – sedovav

+1

當添加ResourceDictionaries時,可能使用以下約定鏈接App.xaml中的其他模塊: ; component/ /Colors.xaml」/> –

+1

as long它的插件庫,我不能在主應用程序 – sedovav

1

我發現,在設計時也工作(至少在VS2010)溶液:

public static class Resource 
{ 
    private static readonly Dictionary<Uri, ResourceDictionary> SharedDictinaries = new Dictionary<Uri, ResourceDictionary>(); 

    private static void onMergedDictionaryChanged(DependencyObject source, DependencyPropertyChangedEventArgs args) 
    { 
     FrameworkElement el = source as FrameworkElement; 
     if (el == null) 
      return; 

     Uri resourceLocator = new Uri(GetMergedDictionary(source), UriKind.Relative); 
     ResourceDictionary dictionary; 
     if (SharedDictinaries.ContainsKey(resourceLocator)) 
      dictionary = SharedDictinaries[resourceLocator]; 
     else 
     { 
      dictionary = (ResourceDictionary)Application.LoadComponent(resourceLocator); 
      SharedDictinaries.Add(resourceLocator, dictionary); 
     } 

     el.Resources.MergedDictionaries.Add(dictionary); 
    } 

    public static readonly DependencyProperty MergedDictionaryProperty = 
     DependencyProperty.RegisterAttached("MergedDictionary", typeof (String), typeof (Resource), new FrameworkPropertyMetadata(null, onMergedDictionaryChanged)); 

    [AttachedPropertyBrowsableForType(typeof(FrameworkElement))] 
    public static String GetMergedDictionary(DependencyObject source) 
    { 
     return (String) source.GetValue(MergedDictionaryProperty); 
    } 

    public static void SetMergedDictionary(DependencyObject source, String value) 
    { 
     source.SetValue(MergedDictionaryProperty, value); 
    } 
} 

此附加屬性可被應用於一個FrameworkElement的。想象一下customLabelStyle是在Edu.Wpf.Example項目的Styles.xaml字典中定義的。所以這種風格可以應用在下一個方面:

<UserControl x:Class="Edu.Wpf.Example.UserControlA" 
    ... 
    xmlns:res="clr-namespace:Edu.Wpf.Example.Resources" 
    res:Resource.MergedDictionary="/Edu.Wpf.Example;component/Resources/Styles.xaml"> 
    ... 
    <Label Style="{StaticResource customLabelStyle}"/> 
</UserControl> 
+0

使用它的鏈接最後我並沒有用這些東西附着打擾,只是在這兩個用戶控件直接添加到URI的樣式resorce字典(「包」語法)在'UserControl.Resources'。 ReSharper處理得更好。 – sedovav

相關問題