【问题标题】:Accessing a resource via codebehind in WPF通过 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");

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

【问题讨论】:

    标签: c# wpf xaml resources code-behind


    【解决方案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 是要走的路。
        猜你喜欢
        • 2010-10-20
        • 1970-01-01
        • 1970-01-01
        • 2012-05-30
        • 1970-01-01
        • 2011-04-02
        • 1970-01-01
        • 1970-01-01
        • 2018-12-02
        相关资源
        最近更新 更多