在用户控件中引用父级的资源字典

发布于 2024-10-14 19:11:17 字数 715 浏览 2 评论 0原文

我有一个 WPF UserControls 库和一个在库内共享的 ResourceDictionary。

该库中的所有用户控件仅出现在单个“外壳”父控件中,该父控件实际上只是较小控件集合的容器。添加以下 XAML 时,我可以按预期从 shell 控件访问 ResourceDictionary

<Control.Resources>
    <ResourceDictionary Source="MyResources.xaml" />
</Control.Resources>

,但是我无法从“shell”控件内的子控件访问 ResourceDictionary。

我的印象是 WPF 应该在本地检查资源,然后向上遍历直到找到合适的资源?

相反,我显然

Cannot find resource named '{BoolInverterConverter}'. 
Resource names are case sensitive.  Error at    
    object 'System.Windows.Data.Binding' in markup file...

可以(并且正在)在我的子控件中引用 ResourceDictionary;但现在每个控件都需要引用这本字典,我认为这是没有必要的。

有什么想法吗,我是在做一些奇怪的事情还是我对行为的期望不正确?

I have a library of WPF UserControls, and a ResourceDictionary that is shared within the library.

All the UserControls in this library appear only within a single 'shell' parent control, which is really just a container for a collection of smaller controls. I'm able to access the ResourceDictionary from my shell control as expected when I add the following XAML

<Control.Resources>
    <ResourceDictionary Source="MyResources.xaml" />
</Control.Resources>

However I can't access the ResourceDictionary from child controls that sit inside the 'shell' control.

I was under the impression that WPF should check locally for resources, and then traverse upwards until appropriate resources are found?

Instead I'm getting

Cannot find resource named '{BoolInverterConverter}'. 
Resource names are case sensitive.  Error at    
    object 'System.Windows.Data.Binding' in markup file...

Obviously I can (and am) referencing the ResourceDictionary in my child controls; but each and every control now needs to reference this dictionary and I believed that this was not necessary.

Any ideas, am I doing something strange or is my expectation of behaviour incorrect?

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

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

发布评论

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

评论(1

月光色 2024-10-21 19:11:17

此处描述了发生的情况,尽管文档有点不透明。如果您将 ResourceDictionary 添加到元素的 Resources 属性而不指定键,WPF 会认为您正在资源字典中进行合并,并且它会使用该元素的内容填充该字典其 MergedDictionaries 属性中的字典。它忽略没有键的 ResourceDictionary 的实际内容。

所以你想要做的是这样的:

<Control.Resources>
   <ResourceDictionary>
      <ResourceDictionary.MergedDictionaries>
         <ResourceDictionary Source="MyResources.xaml"/>
      </ResourceDictionary.MergedDictionaries>
   </ResourceDictionary>
</Control.Resources>

编辑:

一个工作示例:

MainWindow.xaml:

<Window x:Class="MergedDictionariesDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:MergedDictionariesDemo="clr-namespace:MergedDictionariesDemo" Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Dictionary1.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <MergedDictionariesDemo:UserControl1 />
    </Grid>
</Window>

Dictionary1.xaml:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <SolidColorBrush x:Key="UCBrush"
                     Color="Bisque" />
</ResourceDictionary>

UserControl1.xaml:

<UserControl x:Class="MergedDictionariesDemo.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Border Margin="10" BorderBrush="Navy" BorderThickness="1" CornerRadius="10">
        <TextBlock Margin="10"
                   Background="{DynamicResource UCBrush}">
            The background of this is set by the resource UCBrush.
        </TextBlock>

    </Border>
</UserControl>

What's going on is described here, though the documentation's a little opaque. If you add a ResourceDictionary to an element'sResources property without specifying a key, WPF expects that you're merging in resource dictionaries, and it populates the dictionary with the contents of the dictionaries in its MergedDictionaries property. It ignores the actual contents of the ResourceDictionary with no key.

So what you want to do is this:

<Control.Resources>
   <ResourceDictionary>
      <ResourceDictionary.MergedDictionaries>
         <ResourceDictionary Source="MyResources.xaml"/>
      </ResourceDictionary.MergedDictionaries>
   </ResourceDictionary>
</Control.Resources>

Edit:

A working example:

MainWindow.xaml:

<Window x:Class="MergedDictionariesDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:MergedDictionariesDemo="clr-namespace:MergedDictionariesDemo" Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Dictionary1.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <MergedDictionariesDemo:UserControl1 />
    </Grid>
</Window>

Dictionary1.xaml:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <SolidColorBrush x:Key="UCBrush"
                     Color="Bisque" />
</ResourceDictionary>

UserControl1.xaml:

<UserControl x:Class="MergedDictionariesDemo.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Border Margin="10" BorderBrush="Navy" BorderThickness="1" CornerRadius="10">
        <TextBlock Margin="10"
                   Background="{DynamicResource UCBrush}">
            The background of this is set by the resource UCBrush.
        </TextBlock>

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