通过 WPF 中的代码隐藏访问资源

Posted

技术标签:

【中文标题】通过 WPF 中的代码隐藏访问资源【英文标题】:Accessing a resource via codebehind in WPF 【发布时间】:2011-01-08 05:47:06 【问题描述】:

我在我的窗口资源中定义了一个自定义集合,如下所示(在 Sketchflow 应用程序中,因此窗口实际上是一个 UserControl):

<UserControl.Resources>
    <ds:MyCollection x:Key="myKey" x:Name="myName" />
</UserControl.Resources>

我希望能够在代码隐藏中引用这个集合,我希望它是 x:Name,但我似乎无法访问它。

我可以参考它使用

myRef = (MyCollection) this.FindName("myKey");

但这看起来很老套。这是不好的做法,什么会更好?谢谢:)

【问题讨论】:

【参考方案1】:

Microsoft 文档中的一个干净整洁的示例使其变得简单:

private void myButton_Click(object sender, RoutedEventArgs e)

  Button button = (Button)sender;
  button.Background = (Brush)this.FindResource("RainbowBrush");

【讨论】:

【参考方案2】:

我使用下面的代码获得了有关 C#(桌面 WPF W/.NET Framework 4.8)的资源

DefaultNamespace.Properties.Resources.ResourceName

【讨论】:

【参考方案3】:

如果您想从其他类访问资源(例如,不是 xaml 代码隐藏),您可以使用

Application.Current.Resources["resourceName"];

来自System.Windows 命名空间。

【讨论】:

如果您需要从静态构造函数或方法访问资源,因此无法调用FindResourceTryFindResource,这很有用。【参考方案4】:

您应该使用System.Windows.Controls.UserControlFindResource()TryFindResource() 方法。

另外,一个好的做法是创建一个字符串常量,它映射资源字典中的键名(这样您只能在一个地方更改它)。

【讨论】:

您可以使用:Application.Current.FindResource(errorColorResourceName) 作为 MyCollection 或 this.FindResource("RainbowBrush") 作为 MyCollection。这取决于上下文。 您能否详细说明“另外,一个好的做法是创建一个字符串常量,它映射资源字典中的键名(这样您只能在一个地方更改它)。” ?这样一个字符串常量会改变 XAML 键以及背后的 C# 代码? +1 for > 你能详细说明一下“另外,一个好的做法是创建一个字符串常量,它映射资源字典中的键名(这样你只能在一个地方更改它)。” ?这样一个字符串常量会改变 XAML 键以及背后的 C# 代码?【参考方案5】:

您可以像这样使用资源键:

<UserControl.Resources>
    <SolidColorBrush x:Key="x:Static local:Foo.MyKey">Blue</SolidColorBrush>
</UserControl.Resources>
<Grid Background="StaticResource x:Static local:Foo.MyKey" />

public partial class Foo : UserControl

    public Foo()
    
        InitializeComponent();
        var brush = (SolidColorBrush)FindResource(MyKey);
    

    public static ResourceKey MyKey  get;  = CreateResourceKey();

    private static ComponentResourceKey CreateResourceKey([CallerMemberName] string caller = null)
    
        return new ComponentResourceKey(typeof(Foo), caller); ;
    

【讨论】:

请注意,这取决于密钥的类型。例如。 DataTemplate 中的键是 DataTemplateKey 类型。【参考方案6】:

不完全直接的答案,但密切相关:

如果资源位于不同的文件中 - 例如 ResourceDictionary.xaml

您可以简单地将x:Class 添加到它:

<ResourceDictionary x:Class="Namespace.NewClassName"
                    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
    <ds:MyCollection x:Key="myKey" x:Name="myName" />
</ResourceDictionary>

然后在后面的代码中使用:

var res = new Namespace.NewClassName();
var col = res["myKey"];

【讨论】:

+1,但为了能够使用它的密钥查找资源,我必须在尝试访问密钥之前调用 res.InitializeComponent(),否则对象将不显示任何密钥,并且对 res["myKey"] 的调用将返回空。 哇,太棒了...我从来不知道你能做到这一点,它只是快速轻松地为我解决了一个问题!我确实需要像@StephenRoss 所说的那样调用 InitializeComponent() ,但除此之外就像一个魅力。 完美的解决方案来自Converters【参考方案7】:

您也可以使用this.Resources["mykey"]。我想这并不比你自己的建议好多少。

【讨论】:

这适用于 Windows 8 应用商店应用程序。 @cederlof,你也可以在 WPF 中使用它。 如果资源在另一个文件中,例如主题颜色,这将不起作用。 FindResource 是要走的路。

以上是关于通过 WPF 中的代码隐藏访问资源的主要内容,如果未能解决你的问题,请参考以下文章

WPF:在代码隐藏中引用应用程序范围的资源

wpf 无法更改代码隐藏中的图像来源

在代码隐藏中的 DataTemplate 中查找 WPF 元素

如何使用 MVVM 自动隐藏 WPF 中的 DataGrid 列? [复制]

所有列的 WPF GridView 共享单元格模板

如何防止屏幕阅读器/旁白阅读隐藏在 WPF 中的控件?