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

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

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

我希望能够在代码后面引用这个集合,我希望它是由 x: Name 命名的,但是我似乎无法访问它。

我可以用

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

但是这看起来有点骇人听闻。这种做法不好吗? 还有什么更好呢? 谢谢。)

118702 次浏览

You should use System.Windows.Controls.UserControl's FindResource() or TryFindResource() methods.

Also, a good practice is to create a string constant which maps the name of your key in the resource dictionary (so that you can change it at only one place).

You may also use this.Resources["mykey"]. I guess that is not much better than your own suggestion.

Not exactly direct answer, but strongly related:

In case the resources are in a different file - for example ResourceDictionary.xaml

You can simply add x:Class to it:

<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>

And then use it in code behind:

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

You can use a resource key like this:

<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); ;
}
}

If you want to access a resource from some other class (i.g. not a xaml codebehind), you can use

Application.Current.Resources["resourceName"];

from System.Windows namespace.

I got the resources on C# (Desktop WPF W/ .NET Framework 4.8) using the code below

{DefaultNamespace}.Properties.Resources.{ResourceName}

A nice clean example from Microsoft documents makes it simple:

private void myButton_Click(object sender, RoutedEventArgs e)
{
Button button = (Button)sender;
button.Background = (Brush)this.FindResource("RainbowBrush");
}