Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a Style that only exists within the context of a ResourceDictionary

How can I create a style that only exists within the context of a ResourceDictionary, but not in the context of controls that include that ResourceDictionary?

For instance, I want to be able to have a ResourceDictionary that looks like this:

<!-- ControlTemplates.xaml -->
<ResourceDictionary>
    <!-- Private Local styles used to set up the publicly usable templates -->
        <Style x:Key="TextBoxes" TargetType="TextBox">
            <Setter Property="TextWrapping" Value="Wrap" />
        </Style>
    <!-- End of Private Local Stuff -->
    <!-- Public Dictionary Resources Follow -->
    <ControlTemplate x:Key="CustomTextBox">
        <TextBox Style="{StaticResource TextBoxes}" />
    </ControlTemplate>
</ResourceDictionary>

And then in some other control or window, I want to be able to go:

<Window>
    <Window.Resources>
        <ResourceDictionary Source="ControlTemplates.xaml">
    </Window.Resources>
    <Grid>
        <!-- This Should Work -->
        <CustomControl Template="{StaticResources CustomTextBox}">

        <!-- This Should NOT Work! -->
        <TextBox Template="{StaticResources TextBoxes}">
    </Grid>
</Window>
like image 273
Alain Avatar asked Oct 14 '11 17:10

Alain


1 Answers

One way to get quite close to what you are looking for is to move the "private" styles from ControlTemplates.xaml into their own ResourceDictionary, and then reference that resource dictionary from within the control templates in ControlTemplates.xaml:

ControlTemplates.xaml:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <!-- By referencing the ResourceDictionary from within the ControlTemplate's
         resources it will only be available for the ControlTemplate and not for those
         who reference ControlTemplates.xaml -->
    <ControlTemplate x:Key="CustomTextBox">
        <ControlTemplate.Resources>
            <ResourceDictionary Source="ControlTemplatePrivateStyles.xaml" />
        </ControlTemplate.Resources>

        <TextBox Style="{StaticResource TextBoxes}" Text="Some text" />
    </ControlTemplate>

</ResourceDictionary>

ControlTemplatePrivateStyles.xaml:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Style x:Key="TextBoxes" TargetType="TextBox">
        <Setter Property="TextWrapping" Value="Wrap" />
    </Style>

</ResourceDictionary>

Then the xaml for the window would look like this:

<Window x:Class="ResourceDictionaryPrivateStyle.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:ResourceDictionaryPrivateStyle="clr-namespace:ResourceDictionaryPrivateStyle"
    Title="MainWindow" Height="350" Width="525">

    <Window.Resources>
        <ResourceDictionary Source="ControlTemplates.xaml" />
    </Window.Resources>

    <StackPanel>
        <!-- This works -->
        <ResourceDictionaryPrivateStyle:CustomControl Template="{StaticResource CustomTextBox}" />

        <!-- This does not work, unless you explicitly reference ControlTemplatesPrivateStyles.xaml here in the window-->
        <TextBox Text="Text" Style="{StaticResource TextBoxes}" />
    </StackPanel>
</Window>

This way you could not use the "private" styles unless you explicitly reference that resource dictionary. They will not be accessible by just referncing the ControlTemplates.xaml resource dictionary.

like image 179
Erik Öjebo Avatar answered Nov 01 '22 11:11

Erik Öjebo