Archive

Archive for the ‘Resources’ Category

Resources in WPF – II (Logical Resources)

February 17, 2009 3 comments

Logical resources are arbitrary .net objects stored (and named) in element’s ResourceDictionary. Logical resource can be shared among multiple elements depending upon the scope at which it has been defined. Both FrameworkElement and FrameworkContentElement has ResourceDictionary defined in it, hence almost all UI elements inherit the ResourceDictionary. Typical logical resources are styles, bindings, etc.

Logical resources are of two types :

1) StaticResources
2) DynamicResources

How resources are searched?

StaticResource/DynamicResource markup extension accepts a key name as parameter. So this key is searched while looking up for resource. It is not mandatory that resource has to be defined on the element which is using it. Xaml looks for the resource at the element level first then to parent level and then to application level. Resource markup extension implements the ability to walk the logical tree to find the items upward in the logical tree so if resource is not found, it checks the parent element, its parent and so on until it reaches the root element. At this point, it checks the resources collection at the application level and system level subsequently. If the resource is not found anywhere, it throws “InvalidOperationException”.

Although it is advisable to have unique key associated with resource, however it is not mandatory. While looking up for the resource whatever  resource is found first is assigned.

Static v/s. Dynamic Resources

Static Resources

Dynamic Resources

StaticResource is applied only once (first time when it is used).

DynamicResource is applied every time when resource changes e.g. system colors can be changed using control panel. So if system colors has been used as resource, than update is required. DynamicResource will take care of such change in resource.

StaticResource has lesser overhead as it is applied only once during the runtime of the application.

DynamicResource has more overhead as it is applied whenever the resource value changes. In order to do this, DynamicResource has to keep tracking about the changes in the resource during runtime also.

StaticResources always get loaded the first time window/page is loaded irrespective of its use during start up.

DynamicResources are not loaded until it is actually used. So this results in better load time.

StaticResources can be used for DependencyProperty as well as normal .net property.

DynamicResource can only be used for DependencyProperty.

StaticResources has to be defined before it is used. Hence, StaticResources can not be forward referenced. DynamicResources can use the forward references.

Defining and Applying Resources from procedural code

At element level adding resources (at definition level, static/dynamic resource is not differentiated) is easy. The syntax is

<element>.Resources.Add(object key, object value);

Static Resource

If in xaml, resources are used as static resource as shown below (provided resource is already defined)

<Button BackGround={StaticResource backgraoundBrush}/>

then from procedural code, this resource can be used as

Button button = new Button();
button.BackGround = (Brush)button.FindResource(“backgroundBrush”);

If “FindResource” fails to find the resource, it throws  “ResourceReferenceKeyNotfoundException”. To avoid this situation, “TryFindResoruce” method can be used which returns ‘null’ if the resource key is not found.

Dynamic Resource

in xaml, dynamic resource can be used as mentioned below :

<Button BackGround={DynamicResource backgraoundBrush}/>

however in procedural code this can be set using SetResourceReference method as shown below :

button.SetResourceReference(Button.BackgroundProperty, “backgroundbrush”);

Do remember that forward reference (i.e. defining the resource before using it) still remains invalid for Static Resource even with procedural code.

Accessing Resources from other assemblies

In many cases resources are defined in separate assembly for the sake of better maintainability. In that case resources can be accessed from different assembly in following way ;

<Button BackGround={DynamicResource {ComponentResourcekey TypeinTargetAssembly=”local:MyResources, ResourceID=backgroundBrush }}

Sometimes the other assembly in which the resource has been defined provides way to access the resource by defining property in class.

public object MyResourceKey

{
      get {return (new ComponentResourcekey (this.GetType(), “backgroundBrush”);}    

}

In such a case, resource can be accessed from xaml in following way :

<Button BackGround=”{DynamicResource {x:static local:MyResourceKey}}”

Accessing System Resources

Sysem Resources i.e. System Fonts, System colors etc. can be used in similar way as mentioned above.

<Button BackGround =”{DynamicResource {x:static SystemColors.Desktopcolor}}”

Advertisements
Categories: Resources, WPF

Resources in WPF – I (Binary Resources)

February 16, 2009 12 comments

There are two types of resources in WPF :

1) Binary Resources
2) Logical Resources

In this post, I have described the details of the Binary resources.

Binary Resources : Binary resources could be logo/image files, AV files etc. Resource files which are added to project, can have the “Build Action” defined on it from the file properties windows.

Out of the various build actions defined by WPF only following two are important for binary resources :

image

  • Resource : Embeds resource into the assembly (or culture specific satellite assembly)
  • Content : this leaves resource as loose file and upon compilation this resource information is not embedded to assembly. Instead, it adds custom attribute to the assembly (AssemblyAssociatedContentFile) which records the existence and relative location of file.It is also possible to access the resource file without adding into the project however with this approach management of resource file becomes bit difficult. However, this approach is useful is resource file is generated dynamically using some runtime information. In such a case, resource file will not be available at compile time so can not be added to project.

What is the difference between the “Resource” and “Embedded Resource” build actions?
“Resource” and “Content” build actions are to access the WPF resources using the Uris. However “Embedded Resource” is for prior technologies. However both options embeds the resource in assembly but “Resource” option to be used for WPF.

URIs for accessing the binary resources

URI

Resource

“Logo.jpg”
  • embedded in current assembly (using “Resource” as build action)
  • loose resource however physical file is placed along with xaml file or assembly (if selected build action is “Content”)
“A/B/Logo.jpg” same as above but resource file is located in subfolder “A/B”
“D:\Resource\Logo.jpg” resource path hard coded
http://pinvoke.net/logo.jpg loose resource hosted at pinvoke.net website.
ResourceDll;component/Logo.jpg this URI represents the resource embedded in assembly ResourceDLL.dll or ResourceDLL.exe
ResourceDll;componen/tA/B/Logo.jpg same as above except resource is located in subfolder
pack://siteOfOrigin:,,,/logo.jpg resource located at site of origin
pack://siteOfOrigin:,,,/A/B/logo.jpg resource located at site of origin in sub folder

Site of Origin :

Site of origin at the runtime gets resolved in different ways depending upon the way in which the application has been deployed.

  • For a full-trust application installed with Windows Installer, the site of origin is the application’s root folder.
  • For a full-trust ClickOnce application, the site of origin is the URL or Universal Naming Convention (UNC) path from which the application was deployed.
  • For a partial-trust XAML Browser Application (XBAP) or ClickOnce application, the site of origin is the URL or UNC path that hosts the application.
  • For loose XAML pages viewed in Internet Explorer, there is no site of origin. Attempting to use it throws an exception.

Accessing resources from procedural code :

While accessing the resource from procedural code in WPF, triple comma syntax is used however above table for URIs remains still applicable except the last two rows with site of origin.
e.g. to read the embedded resource with “Resource” action “pack://application:,,,/logo.jpg’” can be used.

Following code shows how to read the resource from procedural code :

Image image = new Image();
image.Source = new BitmapImage(new Uri(“pack://application:,,,/logo.jpg”))

There is one more aspect to binary resource and that is localization but I’m not covering it as of now.