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

C#WpfResources

C# Problem Overview


I have a DataTemplate defined in a xaml file that I want to access via C# code. Can anyone please tell me how can I access it? I added a new ResourceDictionary file and its name is Dictionary1.xaml. I have a data template such as:

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

not I have a ListBox called listBox1 and I want to assign it to it's Itemtemplate property but I'm not getting how can i do it?

C# Solutions


Solution 1 - C#

Since Application.Current was null in my case, I've ended up using this:

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

and then getting the specified key I needed by using myResourceDictionary["KeyName"] as TypeOfItem

(source)

Solution 2 - C#

Where exactly are you defining it?

If you define it in the ResourceDictionary of your object, then

Application.Current.Resources[typeof(yourDataTemplateTargetType)] 

should work. If you are defining it as a member of something else, like say, an ItemsControl, you need to get a handle to the ItemsControl instance and call the ItemTemplate property.

Edit: Ok, I think we're getting somewhere. So you are defining a ResourceDictionary in its own file. Before you can use it in your UI and access it from your code behind, you need to merge that ResourceDictionary into your application. Are you doing this?

If you are, then the next step is to get this resource. Each FrameworkElement has a method called FindResource. This method is great because it walks up the ResourceDictionary tree and attempts to locate the resource with the key. So, if you want to access this resource from a UserControl, you can do the following in the code behind:

FindResource(typeof(yourDataTemplateTargetType));

If this doesn't work for you, please show us exactly how you are declaring this resource dictionary and how it is getting merged into your application's resources.

Solution 3 - C#

If you for example have a template for Button in your resource dictionary in the App.xaml file you can access it using the following code:

Application.Current.Resources[typeof(Button)]

Solution 4 - C#

If you're getting the resources within the same project, try this:

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

Otherwise, try this:

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

Solution 5 - C#

If you have merged resource dictionary using code like below

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

Then, instead of Application.Current.Resources["ResourceKey"] you need to specify Control name (in this case MainWindow) also like below

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

Solution 6 - C#

You can access a resource dictionary you added to your project as follows:

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

Then you can access a resource stored in the resource dictionary like so:

someObject.Property = rd["mytemplate"];

NOTE:
You will have to modify the URI to the resource dictionary according to the location you created it relative to the project's base directory.

Solution 7 - C#

I found the answer here

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

  • create a ressource dictionary "ColorResources.xaml"

  • add to it: Blue

  • edit your app.xml and add:

  • use the color from your code

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

and voilĂ 

ps : admin can you fix the code? it does not show up, thanks

Solution 8 - C#

Any of the above approaches work getting the resource based on the location, if you are following MVVMm I would recommend doing it this way:

  1. create a Service like ProvideDataTemplateService, (to create a service usual inherit from Behavior )
  2. Use Container of Your choice to inject this service where you would like to have aces to DataTemple.

Solution 9 - C#

For the life of me, although I was able to load my resource dictionary via XAML, I wasn't able to load it via "code behind" (in C#).

So I resorted to have a view loading it: (MyView.xaml)

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

Then access it in my UT by instanciating that view and accessing it:

new MyView().Resources.MergedDictionaries[0]

Hacky, but works.

Solution 10 - C#

Just to add another answer here in case you don't have a view or Application.Current is null. I realize this is probably uncommon but in my case I have an addin to a parent application and Application.Current is null; I also want to pass one of my resources to the parent as an ImageSource so I don't have a XAML view created to get resources from directly.

You can also make the dictionary into a code behind creatable object. Just set the x:Class attribute in the XAML and then create a .xaml.cs file in the code behind. Your updated XAML, lets call the code file MyDictionary.xaml, would then look something like this:

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

And the code behind (MyDictionary.xaml.cs) would look something like this:

using System.Windows;

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

Don't forget to call InitializeComponent() as that's what loads the resources. Actually not sorry, see edit below

After you do this you can simply construct an instance of the class anywhere in code and reference the resources by key like this:

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

Thanks to this post for leading to the idea.

EDIT

Just ran into one potential issue with this. I got a 'Cannot re-initialize ResourceDictionary instance' exception with this setup on some of my controls. On further research this could be related to calling InitializeComponent in the constructor. Instead I removed the constructor from the code behind and added a static method to get an initialized instance as follows:

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

You could also just create and initialize in your code behind.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEmbedd_0913View Question on Stackoverflow
Solution 1 - C#itshoView Answer on Stackoverflow
Solution 2 - C#Szymon RozgaView Answer on Stackoverflow
Solution 3 - C#Jakob ChristensenView Answer on Stackoverflow
Solution 4 - C#BloggrammerView Answer on Stackoverflow
Solution 5 - C#Ajit1490View Answer on Stackoverflow
Solution 6 - C#Alex EssilfieView Answer on Stackoverflow
Solution 7 - C#PhilView Answer on Stackoverflow
Solution 8 - C#dmanView Answer on Stackoverflow
Solution 9 - C#jeromejView Answer on Stackoverflow
Solution 10 - C#sfaustView Answer on Stackoverflow