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 :
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
Calling a SQL User-Defined Function in a Linq Query
Logoff Interactive Users in Windows from a Service
How to Share Data Between Different Threads in C# Using Aop
Download a File from Azure Devops Server Writes Wrong Data to The File
How to Delete Cookies on an ASP.NET Website
Decrypt String in C# That Was Encrypted with PHP Openssl_Encrypt
Search Xdocument Using Linq Without Knowing the Namespace
Assemblytitle' Attribute in the .Net Framework
Enter Key Pressed Event Handler
Is the Destructor Called If the Constructor Throws an Exception
Creating Safe SQL Statements as Strings
Filesystemwatcher to Watch Unc Path
Getters and Setters Are Bad Oo Design