Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resource dictionary in User control

Tags:

wpf

xaml

.net-4.0

I have a user control and it uses resource dictionaries. In that user control, there is another user control which uses same resource dictionaries.what I want to know is whether wpf actually loads it twice and if yes, is there any perfomance impact. Is there any better way to do this.

Thanks in advance.

like image 925
Dipesh Bhatt Avatar asked Feb 15 '26 08:02

Dipesh Bhatt


1 Answers

Interesting question. I was intrigged enough to investigate. It appears that WPF loads a new ResourceDirectionary (and all resources defined and the dictionary which are used) for each appearance of element.

Take a look at the following code:

ViewModel:

public class Person
{
    public string name { get; set; }
    public int age { get; set; }
    public Person() { }
}

Resource (Dictionary1.xaml):

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:so="clr-namespace:SO"
    >
    <so:Person x:Key="m" name="Methuselah" age="969" />
</ResourceDictionary>

View:

<Window
    x:Class="SO.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:so="clr-namespace:SO"
    Height="200" Width="300"
    Title="SO Sample"
    >
    <Window.Resources>
        <ResourceDictionary Source="Dictionary1.xaml" />
    </Window.Resources>

    <StackPanel DataContext={StaticResource m}>
        <UserControl>
            <UserControl.Resources>
                <ResourceDictionary Source="Dictionary1.xaml" />
            </UserControl.Resources>
            <TextBlock x:Name="inner" DataContext="{StaticResource m}" Text="{Binding Path=name}" />
        </UserControl>        
        <TextBlock x:Name="outer" Text="{Binding Path=name}" />        
        <Button Click="Button_Click">Change</Button>        
    </StackPanel>
</Window>

Put a breakpoint at the Person() constructor and notice the object is instantiated twice. Or, make Person implementing INotifyPropertyChange, and add the following code for Button_Click:

private void Button_Click( object sender, RoutedEventArgs e ) {
    Person innerPerson = this.inner.DataContext as Person;
    Person outerPerson = this.outer.DataContext as Person;
    innerPerson.name = "inner person";
    outerPerson.name = "outer person";
}

If you want to have a single instance of each resource, have the reousrces in the element of app.xaml file.

like image 119
Uri Avatar answered Feb 18 '26 08:02

Uri