簡體   English   中英

如何從 C# 代碼訪問 wpf 中的 ResourceDictionary?

[英]How can I access ResourceDictionary in wpf from C# code?

我在 xaml 文件中定義了一個DataTemplate ,我想通過 C# 代碼訪問該文件。 誰能告訴我如何訪問它? 我添加了一個新的ResourceDictionary文件,它的名稱是Dictionary1.xaml 我有一個數據模板,例如:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <DataTemplate x:Key="mytemplate">
        <TextBlock Text="Name:" Background="Blue"/>
    </DataTemplate>
</ResourceDictionary>

不是我有一個名為 listBox1 的ListBox ,我想將它分配給它的Itemtemplate屬性,但我不知道該怎么做?

由於在我的情況下Application.Current是 null ,我最終使用了這個:

    var myResourceDictionary = new ResourceDictionary();
    myResourceDictionary.Source =
        new Uri("/DllName;component/Resources/MyResourceDictionary.xaml",
                UriKind.RelativeOrAbsolute);  

然后使用myResourceDictionary["KeyName"] as TypeOfItem獲取我需要的指定密鑰

來源

你到底在哪里定義它?

如果您在 object 的 ResourceDictionary 中定義它,那么

Application.Current.Resources[typeof(yourDataTemplateTargetType)] 

應該管用。 如果您將其定義為其他事物的成員,例如 ItemsControl,您需要獲取 ItemsControl 實例的句柄並調用 ItemTemplate 屬性。

編輯:好的,我認為我們正在取得進展。 因此,您在自己的文件中定義了 ResourceDictionary。 在您可以在 UI 中使用它並從后面的代碼中訪問它之前,您需要將該 ResourceDictionary 合並到您的應用程序中。 你在做這個嗎?

如果您是,那么下一步就是獲取此資源。 每個 FrameworkElement 都有一個名為FindResource的方法。 這個方法很棒,因為它遍歷 ResourceDictionary 樹並嘗試使用鍵定位資源。 因此,如果您想從 UserControl 訪問此資源,您可以在后面的代碼中執行以下操作:

FindResource(typeof(yourDataTemplateTargetType));

如果這對您不起作用,請告訴我們您是如何聲明此資源字典的,以及它是如何合並到您的應用程序資源中的。

例如,如果您在 App.xaml 文件的資源字典中有一個 Button 模板,您可以使用以下代碼訪問它:

Application.Current.Resources[typeof(Button)]

如果您在同一個項目中獲取資源,請嘗試以下操作:

yourControl.Style = FindResource("YourResourceKey") as Style;

否則,試試這個:

ResourceDictionary res = (ResourceDictionary)Application.LoadComponent(new Uri("/ProjectName;component/FolderName/ResourceDictionaryName.xaml", UriKind.Relative)); 
yourControl.Style = (Style)res["YourResourceKey"];

您可以訪問添加到項目中的資源字典,如下所示:

var rd = new ResourceDictionary();
rd.Source = new Uri("ms-appx:///Dictionary1.xaml");

然后您可以訪問存儲在資源字典中的資源,如下所示:

someObject.Property = rd["mytemplate"];

筆記:
您必須根據您創建的相對於項目基本目錄的位置來修改資源字典的 URI。

我在這里找到了答案

https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/how-to-use-a-resourcedictionary-to-manage-localizable-string-resources

  • 創建資源字典“ColorResources.xaml”
  • 添加到它:藍色

  • 編輯您的 app.xml 並添加:

  • 使用代碼中的顏色

    var color = (System.Windows.Media.Color)Application.Current.FindResource("ButtonColor1");

ps:管理員可以修復一下代碼嗎? 不顯示,謝謝

如果您使用如下代碼合並了資源字典

<Window x:Class="MainWindow">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="DefaultStyle.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
</Window>

然后,您需要指定控件名稱(在本例中為 MainWindow)而不是 Application.Current.Resources["ResourceKey"],如下所示

var style = Application.Current.MainWindow.Resources["ResourceKey"];
// OR
var style = Application.Current.MainWindow.TryFindResource("ResourceKey");

以上任何一種方法都可以根據位置獲取資源,如果您關注 MVVMm,我建議您這樣做:

  1. 創建一個像 ProvideDataTemplateService 這樣的服務,(創建一個通常繼承自 Behavior 的服務)
  2. 使用您選擇的容器將此服務注入您希望對 DataTemple 擁有 ace 的位置。

對於我的一生,雖然我能夠通過 XAML 加載我的資源字典,但我無法通過“代碼隱藏”(在 C# 中)加載它。

所以我求助於加載它的視圖:(MyView.xaml)

  <UserControl.Resources>
    <ResourceDictionary>
      <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="/My.Proj;component/My/Path/myResourceDictionary.xaml" />
      </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
  </UserControl.Resources>

然后通過實例化該視圖並訪問它在我的 UT 中訪問它:

new MyView().Resources.MergedDictionaries[0]

哈克,但有效。

只是在這里添加另一個答案,以防您沒有視圖或Application.Current是 null。 我意識到這可能並不常見,但在我的情況下,我有一個父應用程序的插件, Application.Current是 null; 我還想將我的資源之一作為ImageSource傳遞給父級,因此我沒有創建 XAML 視圖來直接從中獲取資源。

您還可以將字典制作成可創建 object 后面的代碼。 只需在 XAML 中設置x:Class屬性,然后在后面的代碼中創建一個.xaml.cs文件。 您更新后的 XAML,讓我們調用代碼文件MyDictionary.xaml ,然后看起來像這樣:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                    x:Class="Some.Namespace.MyDictionary"
                    mc:Ignorable="d">
    ...Resources...
</ResourceDictionary>

后面的代碼( MyDictionary.xaml.cs )看起來像這樣:

using System.Windows;

namespace Some.Namespace
{
    public partial class MyDictionary : ResourceDictionary
    {
        public MyDictionary()
        {
            InitializeComponent();
        }
    }
}

不要忘記調用InitializeComponent() ,因為這是加載資源的原因。 其實不抱歉,請參閱下面的編輯

完成此操作后,您可以簡單地在代碼中的任何位置構造 class 的實例,並通過鍵引用資源,如下所示:

var dictionary = new MyDictionary();
var resource = dictionary["whateverKey"] as WhateverResourceType;

感謝這篇文章導致了這個想法。

編輯

剛剛遇到了一個潛在的問題。 在我的某些控件上使用此設置時出現“無法重新初始化 ResourceDictionary 實例”異常。 在進一步的研究中,這可能與在構造函數中調用InitializeComponent有關。 相反,我從后面的代碼中刪除了構造函數,並添加了一個 static 方法來獲取初始化實例,如下所示:

public static MyDictionary ConstructInitializedInstance()
{
    var dictionary = new MyDictionary();
    dictionary.InitializeComponent();
    return dictionary;
}

您也可以在后面的代碼中創建和初始化。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM