以编程方式访问Silverlight静态资源

11

我想以编程方式访问静态资源,就像在XAML中一样:

<TextBlock Text="{Binding Source={StaticResource My.Text.Key}}" />

不管我的静态资源是在TextBlock、某个父元素(例如UserControl)甚至是应用程序上定义,这都可以正常工作。看起来无论是StaticResource绑定表达式还是元素本身都知道如何遍历元素树。我想以编程方式做同样的事情:

<UserControl x:Class="MyCustomControl" ...>
    <UserControl.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Resources.xaml"/> <!-- Sets 'My.Text.Key' to System.String 'Hello, World!' -->
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </UserControl.Resources>
</UserControl>

public partial class MyCustomControl
{
    public MyCustomControl()
    {
        InitializeComponent();
        string myCustomValue = this.Resources[MyCustomValue] as string; // myCustomValue becomes null!
    }
}

即使在这个简单的测试中,我的资源似乎也无法以编程方式访问。而这只是我真正想做的事情的简化版本:通过一个具有自定义动态属性的元素(例如uiElement.Resources[key])找到静态资源。


当我从我的键中去掉“点”(例如,“MyTestKey”而不是“My.Test.Key”)时,我可以开始以编程方式查看我的资源。在XAML或代码后台中,是否有关于资源命名的规则? - Trinition
1个回答

17

尽管您的评论不同,但我怀疑在您的资源键中使用 "." 不是您问题的根源。在这种情况下,"." 没有特殊含义,也不会影响资源的访问方式。(我已经尝试过并未发现任何问题)。

然而,在使用 {StaticResource MyName} 标记扩展和尝试以编程方式查找资源之间存在很大的区别。

标记扩展会导致 XamlParser 在指定键的 FrameworkElementResources 属性中查找要分配的属性所属的元素。如果找不到该键,则会在父 FrameworkElement 中查找,并继续直到到达根 FrameworkElement。如果仍然找不到它,则在应用程序的 Resources 属性中查找。

另一方面,这段代码:-

string myCustomValue = this.Resources[MyCustomValue] as string;

在用户控件中,只在单个资源属性中查找。不尝试在祖先或应用程序资源中查找键。这是一个简单的字典查找。我怀疑这就是你真正困扰的地方。

话虽如此,我认为在资源键中使用“.”可能不是一个好主意。“.” 在各种 XAML 场景中已经有含义,因此在键名中使用它也有可能会让开发人员阅读代码时感到困惑,即使Silverlight十分适用于此。


你的回答正是我所需要的:XAML解析时资源查找是分层的,而以编程方式访问资源则不是。虽然我希望 XAML 解析器使用的分层逻辑也可以用于编程访问。我并不认为点号会造成问题。不过点号确实会导致 ReSharper 的语法高亮出现混淆。我的意图是使用点号更好地将资源分隔成伪命名空间,这样每个 Prism 模块都可以定义资源,并避免与其他模块发生冲突。 - Trinition

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接