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

2

7

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.

Brocket answered 13/2, 2013 at 8:50 Comment(0)
B
8

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.

Brietta answered 13/2, 2013 at 9:12 Comment(2)
Thanks. But, I can't use that attribute as reason mentioned in my Edit: part of the question.Brocket
And you use the above example you would use the following tag. <StaticResource ResourceKey="buttonResource" />Bluey
U
4

Try:

<Style TargetType="Button" x:Key="buttonResource">
    <Setter Property="Content" Value="{Binding BoundText}" />
</Style>

<Button Style="{StaticResource buttonResource}" />
Universalism answered 13/2, 2013 at 9:11 Comment(4)
Thanks. I updated my question to include the usage of Content Control, how do I bind the ContentControl in each WPF Window (.xaml) to Button resource in resource dictionary as per above answer?Brocket
I don't see how that would be different. Can you post the code of your ContentControl?Universalism
I added the code for usage of ContentControl in both Window.xaml files.. The actual usage is not of a button but a different control and its because we want to change the resource xaml file in future versions without having to change the Window.xaml file code...Brocket
In the example I wrote buttonResource is no longer a Button, but a style, so you can't use it for the Content property of a ContentControl. In that case you should try the example code from @Alex and set the x:Shared attribute to false.Universalism

© 2022 - 2024 — McMap. All rights reserved.