在另一个StaticResource中引用StaticResource [英] Referencing a StaticResource in another StaticResource

查看:101
本文介绍了在另一个StaticResource中引用StaticResource的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


您好,

我正在尝试正确设置我的样式。因此,我为所有常见的样式属性创建了一个外部的ResourceDictionary,其中我定义了一个默认的字体系列:

I'm trying to set up my styles properly. Thus I've created an external ResourceDictionary for all common style attributes, in which I've defined a default font family like this:

<FontFamily x:Key="Default.FontFamily">Impact</FontFamily>

这样,当我更改此单行时,系列会在所有位置发生变化。

This way the family changes at all places when I change this single line.

使用和引用StaticResource

现在我想在没有其他任何内容的地方使用这个默认字体系列,这在大多数地方都是如此(但不是所有)。但是,我希望保留为使用它的任何地方定义其他字体系列的能力。因此,我为组框标题明确定义了默认字体

Now I want to use this default font family wherever nothing else is defined, which is in most places (but not all). However, I want to retain the ability of defining other font families for any place this is used. So I defined the default font explicitly for a group box header:

<StaticResource x:Key="GroupBox.HeaderFontFamily" ResourceKey="Default.FontFamily"/>

我在包含在我的群组模板中的  TextBlock上使用此功能。

I use this on a TextBlock that is included in a template of my group box.

<Style x:Key="GroupBoxHeaderTextStyle" TargetType="{x:Type TextBlock}">
    <Setter Property="FontFamily" Value="{StaticResource GroupBox.HeaderFontFamily}"/>
</Style>

到目前为止,这是有效的。但是,只要我添加另一行:

So far, this is working. However, as soon as I add another line:

<StaticResource x:Key="GroupBox.HeaderFontFamily" ResourceKey="Default.FontFamily"/>
<StaticResource x:Key="FormLabel.FontFamily" ResourceKey="Default.FontFamily"/>

我抛出此异常:

例外:无法找到资源命名为'Hsetu.GroupBox.HeaderFontFamily'。资源名称区分大小写。

所以我经历过WPF无法找到一个元素,当后面跟着一个  StaticResource (是的,这也算其他元素)比起StaticResources。例如,如果我试图直接解决字体系列 "Default.FontFamily" 直接
我会得到同样的错误,因为它在一个  StaticResource 元素之前)

So I've experienced that WPF cannot find an Element directly addressed when followed by a StaticResource (Yes, this also counts for elements other than StaticResources. eg, if I tried to address the font family "Default.FontFamily" directly I would get the same error, because it precedes a StaticResource element)

使用DynamicResource并引用StaticResource

我尝试过使用动态资源,因为我在示例中读到过类似的问题:

I've tried using a DynamicResource as I've read in an example to a similar problem:

<DynamicResource x:Key="GroupBox.HeaderFontFamily" ResourceKey="Default.FontFamily"/>
<DynamicResource x:Key="FormLabel.FontFamily" ResourceKey="Default.FontFamily"/>

这会引发以下错误:

ArgumentException:'System。 Windows.ResourceReferenceExpression'不是属性'FontFamily'的有效值。

使用和引用DynamicResource

在我的组框样式中使用  DynamicResource仅更改了错误消息:

Using DynamicResource in my group box style only changed the error message:

<Style x:Key="GroupBoxHeaderTextStyle" TargetType="{x:Type TextBlock}">
    <Setter Property="FontFamily" Value="{DynamicResource GroupBox.HeaderFontFamily}"/>
</Style>

System.InvalidCastException:'无法将'System.Windows.ResourceReferenceExpression'类型的对象强制转换为'System.Windows .Media.FontFamily'。'

添加虚拟元素

所以,仅作为此问题当我的StaticResource跟随另一个时,我会想到在资源之间包含一个虚拟元素。

So, as this problem only occurs when my StaticResource is followed by another, I've got the idea of including a dummy element between the resources.

<StaticResource x:Key="GroupBox.HeaderFontFamily" ResourceKey="Default.FontFamily"/>
<Separator x:Key="Dummy"/>
<StaticResource x:Key="FormLabel.FontFamily" ResourceKey="Default.FontFamily"/>

现在,这可行。 万岁!等等一下......继续,我试着用第二个资源 "FormLabel.FontFamily"

Now, this works. Hooray! But wait a minute... continuing on, I tried to use the second resource "FormLabel.FontFamily"

<Style x:Key="FormLabelStyle" TargetType="{x:Type Label}">
    <Setter Property="FontFamily" Value="{StaticResource FormLabel.FontFamily}"/>
</Style>

现在抛出另一个异常:

System.InvalidCastException:'无法将'System.Windows.Controls.Separator'类型的对象强制转换为'System.Windows.Media.FontFamily'。'

错误?

我甚至没有使用 分隔符,所以发生了什么?我假设,在寻址一个StaticResource时,WPF实际上试图使用前面的元素 - 它只在开头工作,因为前面的元素是一个  FontFamily 
的机会 - 而不是与资源键引用的元素。同时,直接渲染前面的元素不可访问。为了确认我的怀疑,我已将其与另一个FontFamily替换为分隔符。

I'm not even using the Separator at all, so what is going on? I assume, when addressing a StaticResource, WPF actually tries to use the preceding element - which only worked in the beginning because the preceding element was a FontFamily by chance - and not the element that is referenced with the ResourceKey. At the same time, rendering the preceding element inaccessible directly. In order to confirm my suspicion, I've replaced the Separator with another FontFamily.

<StaticResource x:Key="GroupBox.HeaderFontFamily" ResourceKey="Default.FontFamily"/>
<FontFamily x:Key="Dummy">Courier New</FontFamily>
<StaticResource x:Key="FormLabel.FontFamily" ResourceKey="Default.FontFamily"/>

实际上,它有效,但标签现在使用Courier New字体而不是引用的Impact字体。

And indeed, it worked, but the Labels are now using the Courier New font instead of the referenced Impact font.

Btw。这不仅适用于字体系列,还适用于其他属性(FontSize,BorderThickness,FontWeight等)。那么,这实际上是WPF中的一个错误,还是静态资源应该像这样行事(这对我来说没有任何意义)?如何才能在多个地方使用我的字体系列,只定义一次?

Btw. this does not only happen with font families but also other attributes (FontSize, BorderThickness, FontWeight, etc.). So, is this actually a bug in WPF or are StaticResources supposed to act like this (which wouldn't make any sense to me)? How can I get to use my font family in multiple places only defining it once?


推荐答案

嗨Otto,

为了使用StaticResource,必须在尝试将其应用到同一可视树中的元素之前定义样式。$


您可以将资源字典添加到可视树中GroupBox上方的控件资源

In order to use StaticResource, the style has to be defined before the element you are trying to apply it to within the same visual tree.

You could add your resource dictionary to a control's resources above the GroupBox in the visual tree

ResourceDictionary:

ResourceDictionary:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Test3.Resourcedctionary">
    <FontFamily x:Key="Default.FontFamily">Comic Sans MS</FontFamily>
    <StaticResource x:Key="HeaderFontFamily1" ResourceKey="Default.FontFamily" />
    <Style x:Key="GroupBoxHeaderTextStyle1" TargetType="GroupBox">
        <Style.Resources>
            <Style TargetType="{x:Type TextBlock}">
                <Setter Property="FontFamily" Value="{DynamicResource HeaderFontFamily1}" />
            </Style>
        </Style.Resources>
    </Style>

    <Style x:Key="MyGroupBoxStyle1" TargetType="{x:Type GroupBox}">
        <Setter Property="HeaderTemplate">
            <Setter.Value>
                <DataTemplate>
                    <TextBlock FontFamily="{DynamicResource HeaderFontFamily1}" Text="{Binding}" />
                </DataTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

App.xaml:

 <Application.Resources>

        <ResourceDictionary>
           
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Resourcedctionary/Dictionary1.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>


    </Application.Resources>


 <GroupBox
            Name="group1"
            Width="200"
            Height="200"
            Header="testgroupbox"
            Style="{StaticResource MyGroupBoxStyle1}">
            <StackPanel>
                <TextBlock
                    Name="textblock"
                    Width="200"
                    Height="30"
                    Text="this is one test" />
                <TextBlock
                    Name="textblock1"
                    Width="200"
                    Height="30"
                    Text="this is two test" />
                <TextBlock
                    Name="textblock2"
                    Width="200"
                    Height="30"
                    Text="this is third test" />
            </StackPanel>


        </GroupBox>

或者您可以使用DynamicResource,它不需要样式处于同一级别在可视化树中或以上。

or instead you could use DynamicResource, which does not require the style to be at the same level or above in the visual tree.

<Window.Resources>
        <StaticResource x:Key="HeaderFontFamily" ResourceKey="Default.FontFamily" />
        <StaticResource x:Key="LabelFontFamily" ResourceKey="Default.FontFamily" />
        <Style x:Key="MyGroupBoxStyle" TargetType="{x:Type GroupBox}">
            <Setter Property="HeaderTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <TextBlock FontFamily="{DynamicResource HeaderFontFamily}" Text="{Binding}" />
                    </DataTemplate>
                </Setter.Value>
            </Setter>
        </Style>

        <Style x:Key="GroupBoxHeaderTextStyle" TargetType="GroupBox">
            <Style.Resources>
                <Style TargetType="{x:Type TextBlock}">
                    <Setter Property="FontFamily" Value="{StaticResource HeaderFontFamily}" />
                </Style>
            </Style.Resources>
        </Style>

        <Style x:Key="LabelTextStyle" TargetType="{x:Type Label}">
            <Setter Property="FontFamily" Value="{StaticResource LabelFontFamily}" />
        </Style>
        
    </Window.Resources>
    <StackPanel>
       
        <GroupBox
            Name="group1"
            Width="200"
            Height="200"
            Header="testgroupbox"
            Style="{StaticResource MyGroupBoxStyle}">
            <StackPanel>
                <TextBlock
                    Name="textblock"
                    Width="200"
                    Height="30"
                    Text="this is one test" />
                <TextBlock
                    Name="textblock1"
                    Width="200"
                    Height="30"
                    Text="this is two test" />
                <TextBlock
                    Name="textblock2"
                    Width="200"
                    Height="30"
                    Text="this is third test" />
            </StackPanel>
        </GroupBox>
        <Label
            Name="label1"
            Width="200"
            Height="30"
            Content="this is a test label"
            Style="{StaticResource LabelTextStyle}" />
    </StackPanel>


您可以解决您的问题。

最好的问候,

You can resolve your issue.

Best Regards,

樱桃


这篇关于在另一个StaticResource中引用StaticResource的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆