How to Access Resourcedictionary in Wpf from C# Code

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

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.

Access ResourceDictionary by name

Since you cannot define a key nor a name for such resource, here's what you need to do:

Make your dictionary a resource :

Sample Image

Load your dictionary, keep a reference to it and do whatever you have to do with it.

// Load the dictionary
ResourceDictionary resourceDictionary = null;
var resourceStream = Application.GetResourceStream(new Uri("ResourceDictionary1.xaml", UriKind.Relative));
if (resourceStream != null && resourceStream.Stream != null)
{
using (XmlReader xmlReader = XmlReader.Create(resourceStream.Stream))
{
resourceDictionary = XamlReader.Load(xmlReader) as ResourceDictionary;
}
}

Then add it to your application :

// Merge it with the app dictionnaries
App.Current.Resources.MergedDictionaries.Add(resourceDictionary);

(from the docs Merged Resource Dictionaries)

This exactly replicates the original behavior but now you can access the dictionary.

For design-time you will certainly want the default behavior of having the dictionaries declared in XAML, what you can do then at run-time is to delete all the dictionaries and reload them using the above method.

Accessing a resource via codebehind in WPF

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

Access ResourceDictionary from another assembly in Code

Try this:

`Application.LoadComponent(new Uri("pack://application:,,,/BaseLib.WPF.Skinning;component/BaseStyles.xaml")`

Uri need's String type argument ... http://msdn.microsoft.com/en-us/library/system.uri(v=vs.110).aspx

How to access UI control from code-behind of ResourceDictionary

First of all, Style.Resource is a ResourceDictionary, and there are two important things to notice in the ResourceDictionary.FindName method documentation:

Summary section saying:

Not supported by this Dictionary implementation.

and Return Value section saying:

Always returns null.

Second of all, even if you tried to retrieve the ViewBox by key, it would have to be defined as a resource:

<Style x:Key="MyCustomWindowStyle" TargetType="{x:Type Window}">
<Style.Resources>
<ViewBox x:Key="HamburgerMenu" />
</Style.Resources>
</Style>

And it is not. It is a part of ControlTemplate's visual tree.

Third of all, ControlTemplate does not contain actual elements, but rather a recipe for creating them. So there's no actual ViewBox living inside the ControlTemplate to retrieve. Notice that ControlTemplate.FindName takes an additional parameter specifying an element for which the template was realized.

However, ControlTemplate does have a LoadContent method, which basically loads the visual tree defined by that template, and I think you could use it, and then invoke FindName on the root element. To simplify retrieval of the ControlTemplate let's first make it a resource:

<Style x:Key="MyCustomWindowStyle" TargetType="{x:Type Window}">
<Style.Resources>
<ControlTemplate x:Key="Template" TargetType="{x:Type Window}">
<Grid>
(...)
<ViewBox x:Key="HamburgerMenu" />
(...)
</Grid>
</ControlTemplate>
</Style.Resources>
<Setter Property="Template" Value="{StaticResource Template}" />
</Style>

Then this should do the trick for you:

var window = (Style)Application.Current.Resources["MyCustomWindowStyle"];
var template = (ControlTemplate)window.Resources["Template"];
var root = (FrameworkElement)template.LoadContent();
var hm = (ViewBox)root.FindName("HamburgerMenu");

Update

If your goal is to get hold of the ViewBox in an existing window with that template applied, first you need to know how to get hold of that particular window. It could be the Application.Current.MainWindow, otherwise you're highly likely to find it in the Application.Current.Windows collection. You could also implement the singleton pattern for that window, or use other methods like exposing a static property with reference to that window somewhere in your application, or using third-party tools, such as Service Locator in Prism.

Once you have the window in your hand, you only need to use the previously mentioned ControlTemplate.FindName method:

var window = (...);
var hm = (ViewBox)window.Template.FindName(name: "HamburgerMenu", templatedParent: window);

Note that accessing the resource dictionary in which the template was defined is not necessary.

As for why your attempts with previous solution failed - that's because ControlTemplate.LoadContent method yields freshly created element each time it is invoked, and modifying it does not reflect on elements previously created by that template.

How do I access a resource(style) through code?

For any descendants: here is how I succeded to apply a style from a resource to a dynamically created control through code. (Given that you have a Resource Dictionary containing the style)

First step: Include the Resource Dictionary

To make a Resource Dictionary easily accessible from code, add it through code.

VB

  Dim myResourceDictionary As New ResourceDictionary
myResourceDictionary .Source = New _
Uri("/YourApplication;component/YourDictionary.xaml",
UriKind.RelativeOrAbsolute)

C#

   var myResourceDictionary = new ResourceDictionary
{
Source = new Uri("/YourApplication;component/YourDictionary.xaml", UriKind.RelativeOrAbsolute)
};

Replace "YourApplication" with your solution name, and "YourDictionary" with your Resource Dictionary file.

Second step: Assign the Style

To make use of the newly imported Resource Dictionary, simply assign a control a style;

VB

  Dim myButton As New Button
Dim myButtonStyle As Style = myResourceDictionary("YourStyleKey")
myButton.Style = myButtonStyle

C#

  var myButtonStyle= myResourceDictionary["YourStyleKey"] as Style;
var myButton = new Button { Style = myButtonStyle };

Special thanks to user Stefan Denchev for giving me an article covering this.
As C# isn't my strong side, please edit this if I've made any mistake.

How to get the value from a resource dictionary (XAML) in C#

To look up app-wide resources from code, use Application.Current.Resources to get the app's resource dictionary, as shown here:

string insertFirstName = Application.Current.Resources["insert_first_name"];

Source



Related Topics



Leave a reply



Submit