在 WPF 用户控件库中的 UserControl 之间共享资源的最简单方法是什么?

发布于 2024-11-25 13:35:10 字数 933 浏览 5 评论 0原文

其中有一个WPF用户控件库和两个(或更多)用户控件。我需要在两个用户控件中使用相同的样式。我如何分享这种风格? 例如:

这是样式:

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

用户控件 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>

那么如何在库中的用户控件之间共享此样式而不涉及应用程序 app.xaml 资源字典?

更新

我可以将 Themes\Generic.xaml 添加到我的库中并在那里定义样式。但在这种情况下,我必须使用 ComponentResourceKey 作为样式的键。正确的?很长而且不太方便表达...

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:

This is the style:

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

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

So how can I share this style between user controls in the library without involving of the application app.xaml resource dictionary?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

雨的味道风的声音 2024-12-02 13:35:10

假设您有一个资源定义颜色,如下所示:

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

然后,您可以将资源添加到 App.xaml 的 Application.Resources 标记,如下所示:

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

然后,在所有 UserControl 中,您可以如示例代码所示,使用样式或画笔作为 StaticResources。

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:

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

满天都是小星星 2024-12-02 13:35:10

您可以在单独的 ResourceDictionary 中定义共享资源,然后使用 合并词典

You can define the shared resources in a separate ResourceDictionary, then merge them into your UserControl's Resources using MergedDictionaries.

江南烟雨〆相思醉 2024-12-02 13:35:10

我找到了在设计时也有效的解决方案(至少在 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>

I found the solution that works in design time too (at least in 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:

<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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文