11

我已经尝试了一天,但无济于事,在主题中创建一堆画笔,然后在自定义控件中将它们与 DynamicResource 一起使用。我所做的是这样的:

  • 创建包含样式(作品)的主题 generic.xaml
  • 添加字典以合并到 generic.xaml 以包含应用程序中使用的画笔(作品)
  • 使画笔具有 ComponentResourceKey 键(有效)
  • 使控件使用画笔作为静态资源(作品)
  • 使控件使用画笔作为动态资源(不工作,资源跟踪源说了很多:System.Windows.ResourceDictionary Warning: 9 : Resource not found;)
  • 在 App.Resources 中动态添加具有相同键的画笔(适用于动态资源,它会更改颜色,不适用于静态资源,如预期的那样)

所以我的问题是我找不到任何方法来定义主题中的默认值,以便我可以在应用程序中以编程方式更改它们。StaticResource怎么能找到刷子而DynamicResource找不到?!

我必须补充一点,我创建了一个静态类,将组件资源键作为属性保存,然后我在 xaml 中将其用作 {x:Static UI:ResourceScheme.ControlBackgroundKey} 例如。我的问题似乎与此类似:ComponentResourceKey as DynamicResource 问题只是如果我将静态属性键替换为组件资源键的 XAML 标记,它仍然不起作用。

有人可以帮我吗?:(

4

3 回答 3

7

终于修好了。似乎在另一个程序集中拥有组件资源键的类型会导致整个问题。让我总结一下:

  • 有一个资源类将 ComponentResourceKeys 作为静态属性。资源键的构造函数中使用的类型就是这个类的类型。这是在资源程序集中。
  • 另一个程序集中的自定义控件有一个主题,即控件程序集,它使用资源类的属性作为键定义了一些画笔:{x:Static Namespace:ResourceClass.ResourceKeyProperty}
  • 在同一主题中,控件模板使用画笔作为动态资源:{DynamicResource {x:Static Namespace:ResourceClass.ResourceKeyProperty}}
  • 还有一个应用程序使用这些控件并在应用程序资源中动态添加自定义画笔。这些画笔与主题中的画笔具有相同的键。

最终结果是:

  • 控件最初不使用画笔
  • 控件确实使用应用程序资源中添加的画笔
  • 如果在主题中使用 StaticResource,则控件最初使用画笔,但随后会忽略应用程序资源

对此的解决方案似乎是在控件库中移动资源类。

由于我仍然不知道为什么会发生这种情况,这个问题仍然悬而未决,即使略有改变:为什么它在第一种情况下不起作用?

于 2010-08-21T12:27:58.833 回答
7

这就是区别,

StaticResource 在加载时加载,这意味着您正在使用的资源键必须在使用之前进行词法定义。

因此,在自定义控件的情况下,静态资源只能在同一个 generic.xaml 文件中的控件定义之上定义。因此,如果您将画笔放在不同的 xaml 中,它肯定不会在静态资源的情况下工作。

这就是原因,除非 xaml 类型的其他资源在编译时以某种导入的形式包含在同一文件中,否则您不能在文件中使用静态资源。它只是意味着文件/组件/控件的实际 xaml 应该包含您使用的静态资源的实际引用。

现在我怀疑DynamicResource为什么不起作用,那是因为DynamicResource可能只会查看应用程序的(使用控件的地方)ResourceDictionary,而不是generic.xaml。

我不是 100% 确定,但我觉得如果你定义一个自定义控件并且如果你使用 DynamicResource 那么你的资源必须在应用程序的资源字典或控件资源字典的父容器中,但它不能在 generic.xaml .

因为 DynamicResource 只会在控件运行时的逻辑树中查找键,这就是为什么它可能找不到 generic.xaml 中的资源,除非在 Application.Resources 中显式添加 generic.xaml。

摘要: StaticResource必须在编译时在同一个文件中之前在词法上可用,资源将在Application.Resources字典中可用,它仍然可以在逻辑树中找到,但在编译时只能在同一个dll或同一个generic.xaml中找到。

DynamicResource 必须在运行时在 Application.Resources 和控件的逻辑树中进行搜索。

如需更多参考,请查看资源概览

于 2010-08-21T10:03:05.903 回答
2

我试图重现您的问题以测试一些关于它为什么不起作用的理论,但是我无法重现该问题。该设置似乎有效。

因此,我不会描述解决方案,而是描述非工作的重现设置。

解决方案

目标框架:4.6

项目

  • 控件
    • 参考
      • 资源
    • 文件
      • 主题.xaml
  • 资源
    • 文件
      • 键.cs
  • Wpf应用程序
    • 参考
      • 控件
      • 资源
    • 文件
      • 主窗口.xaml

文件内容

主题.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:r="clr-namespace:Resources;assembly=Resources">
    <Color x:Key="{x:Static r:Keys.PrettyColor}">Red</Color>
    <SolidColorBrush x:Key="{x:Static r:Keys.PrettyBrush}" 
                     Color="{DynamicResource {x:Static r:Keys.PrettyColor}}" />
</ResourceDictionary>

键.cs

namespace Resources {
    using System.Windows;

    public static class Keys {
        public static readonly ComponentResourceKey PrettyBrush =
            new ComponentResourceKey(typeof(Keys), Ids.PrettyBrush);

        public static readonly ComponentResourceKey PrettyColor =
            new ComponentResourceKey(typeof(Keys), Ids.PrettyColor);
    }

    public static class Ids {
        public const string PrettyBrush = "PrettyBrush";
        public const string PrettyColor = "PrettyColor";
    }
}

主窗口.xaml

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:resources="clr-namespace:Resources;assembly=Resources"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/Controls;component/Theme.xaml" />
            </ResourceDictionary.MergedDictionaries>
            <Color x:Key="{x:Static resources:Keys.PrettyColor}">Blue</Color>
        </ResourceDictionary>
    </Window.Resources>
    <Border Background="{DynamicResource {x:Static resources:Keys.PrettyBrush}}" />
</Window>

对于懒惰的人,这里有一个截图:

在此处输入图像描述

于 2015-12-20T14:58:26.823 回答