2011-07-20 8 views
8

Istnieje biblioteka kontroli użytkownika WPF i dwa (lub więcej) elementy sterowania użytkownika. Muszę używać tego samego stylu w obu kontrolkach użytkownika. Jak mogę udostępnić ten styl? Na przykład:Jaki jest najprostszy sposób udostępniania zasobów między UserControls w bibliotece kontroli użytkownika WPF?

To styl: kontrola

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

Użytkownik A:

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

UserControl B:

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

Więc jak mogę podzielić ten styl między użytkownikiem kontrolki w bibliotece bez udziału słownika zasobów aplikacji app.xaml?

UPDATE

mogę dodać Themes \ Generic.xaml w mojej bibliotece i zdefiniować tam styl. Ale w tym przypadku muszę użyć ComponentResourceKey jako klucza stylu. Dobrze? Jest to długa i niezbyt wygodna ekspresja ...

Odpowiedz

2

Możesz zdefiniować udostępnione zasoby w oddzielnym ResourceDictionary, a następnie połączyć je ze swoimi zasobami UserControl przy użyciu MergedDictionaries.

12

Załóżmy, że masz jedną kolory zasobów definiowania coś takiego:

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

a drugi określający podstawowe style tak:

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

Następnie można dodać swoje zasoby do aplikacji. XAML za Application.Resources tag jak pokazano tutaj:

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

Następnie we wszystkich UserControls, ty może używać stylów lub pędzli jako StaticResources, jak pokazuje przykładowy kod.

+3

To biblioteka wtyczek. Więc nie mogę używać App.xaml. – sedovav

+1

jego ewentualnego podłączenia innych modułów w App.xaml stosując następującą konwencję podczas dodawania ResourceDictionaries:

+1

jak długo to jest biblioteka wtyczek Nie mogę użyć odnośników do niej w głównej aplikacji – sedovav

1

znalazłem rozwiązanie, które działa w czasie projektowania zbyt (przynajmniej w 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); 
    } 
} 

Ten dołączony nieruchomość może być stosowany do FrameworkElement. Wyobraź sobie, że customLabelStyle jest zdefiniowany w słowniku Styles.xaml w projekcie Edu.Wpf.Example. Tak więc ten styl można zastosować w następujący sposób:

<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

Na koniec nie zawracałem sobie głowy tymi wszystkimi związanymi dodatkami i po prostu dodałem bezpośrednio uri do stylu resorce (składnia "pack") w obu kontrolkach użytkownika w 'UserControl.Resources'. Jest lepiej obsługiwany przez ReSharper. – sedovav

Powiązane problemy