There are a WPF User Control library and two (or more) User Controls in it. I need to use the same style in both user controls. How can I share this style? For example:
有一个WPF用户控件库和两个(或更多)用户控件。我需要在两个用户控件中使用相同的样式。我该如何分享这种风格?例如:
This is the style:
这是风格:
<Style x:Key="customLabelStyle" TargetType="Label">
...
</Style>
User control A:
用户控制A:
<UserControl x:Class="Edu.Wpf.Example.UserControlA"
...xmlns stuff... >
<Grid>
... some xaml markup...
<Label Style="{StaticResource customLabelStyle}"/>
</Grid>
</UserControl>
UserControl B:
UserControl B:
<UserControl x:Class="Edu.Wpf.Example.UserControlB"
...xmlns stuff... >
<Grid>
... some another xaml markup...
<Label Style="{StaticResource customLabelStyle}"/>
</Grid>
</UserControl>
So how can I share this style between user controls in the library without involving of the application app.xaml resource dictionary?
那么如何在不涉及应用程序app.xaml资源字典的情况下在库中的用户控件之间共享此样式?
UPDATE
UPDATE
I can add Themes\Generic.xaml into my library and define the style there. But in this case I have to use ComponentResourceKey as the key of the style. Right? It's long and not very handy expression...
我可以将Themes \ Generic.xaml添加到我的库中并在那里定义样式。但在这种情况下,我必须使用ComponentResourceKey作为样式的关键。对?这很长,而且不是很方便的表达......
3 个解决方案
#1
2
You can define the shared resources in a separate ResourceDictionary
, then merge them into your UserControl
's Resources using MergedDictionaries.
您可以在单独的ResourceDictionary中定义共享资源,然后使用MergedDictionaries将它们合并到UserControl的Resources中。
#2
12
Say that you have one resource defining colors, like this:
假设您有一个定义颜色的资源,如下所示:
<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>
And another one defining some basic styles like this:
另一个定义了一些基本样式:
<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>
You can then add your resources to the App.xaml's Application.Resources tag as shown here:
然后,您可以将资源添加到App.xaml的Application.Resources标记中,如下所示:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="OtherStyles.xaml"/>
<ResourceDictionary Source="Colors.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
Then, in all your UserControls, you can use the styles or brushes as StaticResources as your example code shows.
然后,在所有UserControl中,您可以将样式或画笔用作StaticResources,如示例代码所示。
#3
1
I found the solution that works in design time too (at least in VS2010) :
我发现解决方案也适用于设计时间(至少在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);
}
}
This attached property can be applied to a FrameworkElement. Imagine the customLabelStyle is defined in the Styles.xaml dictionary in the Edu.Wpf.Example project. So this style can be applied in the next way:
此附加属性可以应用于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>
#1
2
You can define the shared resources in a separate ResourceDictionary
, then merge them into your UserControl
's Resources using MergedDictionaries.
您可以在单独的ResourceDictionary中定义共享资源,然后使用MergedDictionaries将它们合并到UserControl的Resources中。
#2
12
Say that you have one resource defining colors, like this:
假设您有一个定义颜色的资源,如下所示:
<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>
And another one defining some basic styles like this:
另一个定义了一些基本样式:
<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>
You can then add your resources to the App.xaml's Application.Resources tag as shown here:
然后,您可以将资源添加到App.xaml的Application.Resources标记中,如下所示:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="OtherStyles.xaml"/>
<ResourceDictionary Source="Colors.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
Then, in all your UserControls, you can use the styles or brushes as StaticResources as your example code shows.
然后,在所有UserControl中,您可以将样式或画笔用作StaticResources,如示例代码所示。
#3
1
I found the solution that works in design time too (at least in VS2010) :
我发现解决方案也适用于设计时间(至少在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);
}
}
This attached property can be applied to a FrameworkElement. Imagine the customLabelStyle is defined in the Styles.xaml dictionary in the Edu.Wpf.Example project. So this style can be applied in the next way:
此附加属性可以应用于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>