1. Binary Resource
WPF supports three binary resources that can be conveniently used in XAML.
- Resource: Embed resources into the assembly, which is a bit like embedded resource. The difference is that WPF packages related resources to the. Resources file, and then the compiler embeds them into the Assembly file. The default URI access method of WPF does not support embedded resource.
- Content: Resources are not embedded in the Assembly. You only need to add a record to the assembly list, which is the same as the method we used to be familiar. The resource file must be deployed to the target directory along with other assembly files.
- Loose File: These types of resources are usually dynamically determined or added during runtime.
WPF passesUniform Resource Identifier (URI)Access related resource files.
(1) access resource/Content Resources
<Image Source = "/a.png"/>
<Image Source = "/XXX/x.png"/>
(2) accessing loose file)
<Image Source = "pack: // siteoforigin:,/a.png"/>
<Image Source = "C:/test/a.png"/>
XAML
The validity of all resources must be verified during compilation. Therefore, a valid URI path must be used when a loose resource file is used. "Pack: //" indicates the package.
Uri, "Pack: // siteoforigin:," indicates to start from the deployment location, and "pack: // application :,,,"
The full path of the above resource should be "pack: // application:,/a.png", but we usually omit it.
<Image Source = "pack: // application:,/a.png"/>
Other URI statements include:
<Image Source = "http://www.qidian.com/images/logo.gif"/>
<Image Source = "// server1/share/logo.gif"/>
<Image Source = "file: // C:/test/logo.gif"/>
(3) Access resource files in other assembly
Providing a replaceable dedicated resource DLL is also a common programming method, especially the multilingual or skin-changing mechanism. The syntax for WPF to access other program funding source files is a bit odd.
Pack: // application:,/assemblyreference; component/resourcename
- Resources of other assemblies must be embedded as resources.
- The backslash before "/assemblyreference" cannot be omitted.
- Component is a keyword and must be included in the URI.
<Image Source = "pack: // application:,/learn. Library; component/s.gif"/>
<Image Source = "/learn. Library; component/s.gif"/>
2. Logical Resources
Logical resources are objects stored in the element resources attribute. These "pre-defined" objects are referenced or shared by one or more sub-elements.
<Window X: class = "learn. WPF. window1"
Xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
Xmlns: x = "http://schemas.microsoft.com/winfx/2006/xaml"
Title = "window1">
<Window. Resources>
<Contentcontrol X: Key = "label1"> Hello, world! </Contentcontrol>
<Imagesource X: Key = "image1">/a.png </imagesource>
</Window. Resources>
<Grid>
<Label content = "{staticresource label1}"/>
<Image Source = "{staticresource image1}"/>
</GRID>
</WINDOW>
Of course, we can also write the following format.
<Window X: class = "learn. WPF. window1"
Xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
Xmlns: x = "http://schemas.microsoft.com/winfx/2006/xaml"
Title = "window1">
<Window. Resources>
<Contentcontrol X: Key = "label1"> Hello, world! </Contentcontrol>
<Imagesource X: Key = "image1">/a.png </imagesource>
</Window. Resources>
<Grid>
<Label>
<Label. content>
<Staticresource resourcekey = "label1"/>
</Label. content>
</Label>
<Image>
<Image. Source>
<Staticresource resourcekey = "image1"/>
</Image. Source>
</Image>
</GRID>
</WINDOW>
We can even use logical resources to define a complete sub-element.
<Window X: class = "learn. WPF. window1"
Xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
Xmlns: x = "http://schemas.microsoft.com/winfx/2006/xaml"
Title = "window1">
<Window. Resources>
<Label X: Key = "label1" content = "Hello, world! "/>
<Image X: Key = "image1" Source = "/a.png"/>
</Window. Resources>
<Grid>
<Staticresource resourcekey = "label1"/>
<Staticresource resourcekey = "image1"/>
</GRID>
</WINDOW>
There is a limit on logical resources, that is, these element objects inherited from visual can only have one parent element, that is, they cannot be used in multiple locations, because the same object instance is referenced multiple times.
<Window X: class = "learn. WPF. window1"
Xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
Xmlns: x = "http://schemas.microsoft.com/winfx/2006/xaml"
Title = "window1">
<Window. Resources>
<Image X: Key = "image1" Source = "/a.png"/>
</Window. Resources>
<Grid>
<Staticresource resourcekey = "image1"/>
<Staticresource resourcekey = "image1"/>
</GRID>
</WINDOW>
You will see the following error message.
The solution is to add "X: Shared = false", so that a new logical resource object will be generated each time a reference is made.
<Window X: class = "learn. WPF. window1"
Xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
Xmlns: x = "http://schemas.microsoft.com/winfx/2006/xaml"
Title = "window1">
<Window. Resources>
<Image X: Key = "image1" X: Shared = "false" Source = "/a.png"/>
</Window. Resources>
<Grid>
<Staticresource resourcekey = "image1"/>
<Staticresource resourcekey = "image1"/>
</GRID>
</WINDOW>
Resource search:
When referencing a logical resource, the system first looks for the parent element resources set. If the set is not found, the upper parent element is checked step by step. If no valid logical resource definition is found for the root element
WPF checks the application. Resources (defined in APP. XAML) and system Attribute Set (systemparamters
). The middle-key names of each independent resource dictionary cannot be repeated, but they are allowed to be repeated in multiple resource dictionaries of different levels. The logical resource item closest to the resource reference is preferred.
<Window X: class = "learn. WPF. window1"
Xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
Xmlns: x = "http://schemas.microsoft.com/winfx/2006/xaml"
Title = "window1">
<Window. Resources>
<Label X: Key = "label1" content = "Hello, world! "/>
</Window. Resources>
<Grid>
<Grid. Resources>
<Label X: Key = "label1" content = "Hello, C #! "/>
</Grid. Resources>
<Stackpanel>
<Staticresource resourcekey = "label1"/>
</Stackpanel>
</GRID>
</WINDOW>
"Hello, C #! ".
Reference and classification of logical resources"Static (staticresource)"And"Dynamic (dynamicresource)"The difference between the two methods is that static reference is only applied when the resource is loaded for the first time, and dynamic reference is applied again when the resource is changed.
<Window X: class = "learn. WPF. window1"
Xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
Xmlns: x = "http://schemas.microsoft.com/winfx/2006/xaml"
Title = "window1">
<Window. Resources>
<Contentcontrol X: Key = "label1" X: Shared = "false"> Hello, world! </Contentcontrol>
</Window. Resources>
<X: code>
Private void button#click (Object sender, routedeventargs E)
{
This. Resources ["label1"] = "Hello, C #! ";
}
</X: code>
<Grid>
<Stackpanel>
<Label X: Name = "label1" content = "{staticresource label1}"/>
<Label X: Name = "label2" content = "{dynamicresource label1}"/>
<Button X: Name = "button1" Click = "button#click"> test </button>
</Stackpanel>
</GRID>
</WINDOW>
After clicking the button, you will find that label2 reflects the modification of the resource in real time.
Dynamic resources can only be used to set dependency attribute values. Therefore, dynamic resources cannot reference a complete Element Object as static resources do.
<Window X: class = "learn. WPF. window1"
Xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
Xmlns: x = "http://schemas.microsoft.com/winfx/2006/xaml"
Title = "window1">
<Window. Resources>
<Label X: Key = "label" X: Shared = "false" content = "Hello, world! "/>
</Window. Resources>
<Grid>
<Stackpanel>
<Dynamicresource resourcekey = "label"/>
</Stackpanel>
</GRID>
</WINDOW>
This causes such an exception, but static resources do not.
Of course, static resources also have another problem, that is, they do not support forward reference. That is to say, we must first define resources before using static references.
<Window X: class = "learn. WPF. window1"
Xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
Xmlns: x = "http://schemas.microsoft.com/winfx/2006/xaml"
Title = "window1">
<Grid>
<Stackpanel>
<Label content = "{staticresource label}"/>
</Stackpanel>
</GRID>
<Window. Resources>
<Contentcontrol X: Key = "label"> Hello, world! </Contentcontrol>
</Window. Resources>
</WINDOW>
A static resource exception occurs, but dynamic resources do not.
If necessary, logic resources can be defined in multiple resource dictionary files.
Dictionary1.xaml
<Resourcedictionary
Xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
Xmlns: x = "http://schemas.microsoft.com/winfx/2006/xaml">
<Contentcontrol X: Key = "label1"> Hello, world! </Contentcontrol>
</Resourcedictionary>
Dictionary2.xaml
<Resourcedictionary
Xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
Xmlns: x = "http://schemas.microsoft.com/winfx/2006/xaml">
<Contentcontrol X: Key = "label2"> hello, C #! </Contentcontrol>
</Resourcedictionary>
Window1.xaml
<Window X: class = "learn. WPF. window1"
Xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
Xmlns: x = "http://schemas.microsoft.com/winfx/2006/xaml"
Title = "window1">
<Window. Resources>
<Resourcedictionary>
<Resourcedictionary. mergeddictionaries>
<Resourcedictionary source = "dictionary1.xaml"/>
<Resourcedictionary source = "dictionary2.xaml"/>
</Resourcedictionary. mergeddictionaries>
</Resourcedictionary>
</Window. Resources>
<Grid>
<Stackpanel>
<Label content = "{dynamicresource label1}"/>
<Label content = "{dynamicresource label2}"/>
</Stackpanel>
</GRID>
</WINDOW>
If the merged dictionary contains duplicate key values, the last added resource takes priority. For example, dictionary1.xaml and dictionary2.xaml both have an X: Key = "label1" resource, so dictionary2.label1 will win.
In the program code, we can use findresource/tryfindresource to set static resources and setresourcereference to set dynamic resources.
This. labela. content = (contentcontrol) This. labela. findresource ("key1"); // staticresource
This. labelb. setresourcereference (Label. contentproperty, "key2"); // dynamicresource