通过 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
命名空间。
【讨论】:
如果您需要从静态构造函数或方法访问资源,因此无法调用FindResource
或TryFindResource
,这很有用。【参考方案4】:
您应该使用System.Windows.Controls.UserControl
的FindResource()
或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 中的代码隐藏访问资源的主要内容,如果未能解决你的问题,请参考以下文章
在代码隐藏中的 DataTemplate 中查找 WPF 元素