Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF Controls as StaticResource in Resource Dictionary, used in multiple WPF Windows?

I have a Button control as a resource in Resource Dictionary as below:

<!--ButtonResources.xaml file-->
<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Button x:Key="buttonResource" Content={Binding BoundText}/>
</ResourceDictionary>
<!--ButtonResources.xaml file-->

I now use this above button control bound to Content property of ContentControl controls in 2 different Windows .xaml files where each Window has its own DataContext and thus each window should display the Content of above button control based on its ViewModel's BoundText property value as below for each Window.

<Window x:Class="TestClass1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="ButtonResources.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <ContentControl Content={StaticResource buttonResource}/>
    </Grid>
</Window>

But, the problem is that both Window's display same value for the BoundText property which means that both the WPF Windows have same instance of button control from resource, used in both the Windows.

How can I resolve this problem such that each Window gets a separate button control from the resource and still display different values for the BoundText property from their own ViewModel?

Edit: For the reason mentioned in MSDN as below, I can't use x:Shared="False" attribute to resolve this:

•The ResourceDictionary that contains the items must not be nested within another ResourceDictionary. For example, you cannot use x:Shared for items in a ResourceDictionary that is within a Style that is already a ResourceDictionary item.

like image 546
VSS Avatar asked Feb 13 '13 08:02

VSS


People also ask

What's the difference between StaticResource and DynamicResource in WPF?

StaticResource are retrieved only once by the referencing element and used for entire life of the resource. On the other hand, DynamicResource are acquired every time the referenced object is used.

What all we can store in a resource dictionary?

In Extensible Application Markup Language (XAML), the ResourceDictionary class is typically an implicit collection element that is the object element value of several Resources properties, when given in property element syntax.

How do you reference a resource dictionary?

You can reference a resource throughout an app or from any XAML page within it. You can define your resources using a ResourceDictionary element from the Windows Runtime XAML. Then, you can reference your resources by using a StaticResource markup extension or ThemeResource markup extension.

Which are valid types of resources in WPF?

WPF supports different types of resources. These resources are primarily two types of resources: XAML resources and resource data files. Examples of XAML resources include brushes and styles. Resource data files are non-executable data files that an application needs.

How to use resourcedictionary in WPF?

WPF has 2 types of resources. How to declare: here we can declare Resources as per their usage scope. There are 4 ways: Once you are finished with defining a ResourceDictionary, you can add it inside a App.xaml if you wanted to use it across the application.

How to use staticresource and dynamicresource in WPF?

It's very simple, just use StaticResource or DynamicResource tag, as per the application's requirements. Let's go ahead and create a WPF application. It will not change once it's assigned and they are applied at the compiled time only.

What is the difference between themeresource and staticresource?

A ThemeResource is similar to a StaticResource, but the resource lookup is reevaluated when the theme changes. In this example, you set the foreground of a TextBlock to a value from the current theme.

How do I refer to a resource in XAML?

To refer to a XAML resource later, you specify a key for a resource that acts like its name. You can reference a resource throughout an app or from any XAML page within it. You can define your resources using a ResourceDictionary element from the Windows Runtime XAML.


1 Answers

Did you try to use the x:Shared attribute?

<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Button x:Shared="False" x:Key="buttonResource" Content={Binding BoundText}/>
</ResourceDictionary>

For more info read here.

In case this does not work, you can store a template in your resource, instead of the button and use a ContentControl inside your window to display it.

like image 102
Alex Shtof Avatar answered Sep 22 '22 22:09

Alex Shtof