3

If I have some resource defined in resources section of a control or in external resource dictionary, how can I define the same resource with another key? I mean how can I define resource entry that is just reference to another already existing entry?

To be more clear, I want to have several keys referencing one resource just like in programming language I can define several names for one constant. Is it possible?

I've tried that way

<Window.Resources>
    <SolidColorBrush x:Key="Brush1" Color="#FFDF7B04"/>

    <RadialGradientBrush x:Key="Brush2" GradientOrigin="0.5,0.5" Center="0.5,0.5" RadiusX="0.5" RadiusY="0.5">
        <GradientStop Color="#5060FF40" Offset="0" />
        <GradientStop Color="#5060FF40" Offset="0.1" />
        <GradientStop Color="#3560FF40" Offset="0.4" />
        <GradientStop Color="#0860FF40" Offset="0.8" />
        <GradientStop Color="#0060FF40" Offset="1" />
    </RadialGradientBrush>

    <Style x:Key="CustomStyle" TargetType="UserControl">
        <Style.Resources>
            <StaticResource x:Key="TheBrush" ResourceKey="Brush1"/>
        </Style.Resources>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="UserControl">
                    <Border x:Name="Border" BorderBrush="{StaticResource TheBrush}">
                        <!-- more content with several usings of {StaticResource TheBrush} -->
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

and it even works in design-time just like I need. But not even compiling.

UPD. To make more sense what I really want: In example above the reason why I need resource TheBrush is if sometimes I will decide to replace appearance of "TheBrush" in my style to another brush (say Brush2), I want to make such replacement in only one place. Withal I can't change definition of "Brush1" because it could be already used in many other controls (actually it could be placed in external resource dictionary and maintained by another person).

UPD 2. I am sorry that because of my poor English, I could not find the answer to my question yourself niether make my question correctly. Thanks to H.B. now I see that the key word of what I want is "alias". I'm looking for a way of aliasing resources, and there are many similar questions:

Alias or Reference in ResourceDictionary

Aliasing Resources (WPF)

Redefine/alias a resource in WPF?

etc.

So my question is just a duplicate and could be deleted.

Community
  • 1
  • 1
serges_newj
  • 795
  • 1
  • 13
  • 23
  • You want to use a single resource multiple times, but the resource should not be something that can be used by multiple instances at the same time? – Jai Jun 24 '16 at 09:24
  • @Jai: No. I know about x:Shared attribute. It's not the case. – serges_newj Jun 24 '16 at 09:50

2 Answers2

4

You just have to use DynamicResource for you "renaming" instead of StaticResource, which may not work in all contexts, though.

H.B.
  • 166,899
  • 29
  • 327
  • 400
  • Could you please modify my example to provide behavior that I described in question? As far as i know DynamicResource is useful for run-time resource replacement whereas I just looking for way of convenient maintaining of static resources. – serges_newj Jun 24 '16 at 12:02
  • Just replace `` with `` and `BorderBrush="{StaticResource TheBrush}"` with `BorderBrush="{DynamicResource TheBrush}"`. – H.B. Jun 24 '16 at 12:14
  • I've replaced as you proposed, but still I am getting System.Windows.Markup.XamlParseException on line . It says that one can not use DynamicResourceExtension in "ResourceDictionary" collection. Could you please provide an working solution? – serges_newj Jun 27 '16 at 05:03
  • It should work, are you using something other than pure WPF? Also, this solution is known to cause errors in the designer but should work at runtime. – H.B. Jun 27 '16 at 08:13
  • I'm using pure WPF and it doesn't work. Try to put DynamicResource extension to Resources section rather then to an object's property, and you will see. It seems like my question does not make sense to you. I think I know what are DynamicResources for and it's not the case. – serges_newj Jun 27 '16 at 10:26
  • @Sergey: I know [what you want to do](http://stackoverflow.com/a/4638822/546730), and this is exactly what dynamic resources are used for. I also have done such [aliasing of resources](http://stackoverflow.com/a/4803872/546730) before, it's a rather obvious use case. – H.B. Jun 27 '16 at 12:12
  • As I supposed, you don't understand, what I want to. I know that one can redefine resources for style or template using DynamicResource extension. But in this question I'm looking for a way to reference a resource by key other then that it was defined with. – serges_newj Jun 27 '16 at 12:58
  • Sorry, i've missed the second link. It's pretty the same what I wish, but I need it not only for colors, but also for brushes, effects etc. But as I said, I still getting XamlParseException for some reason. – serges_newj Jun 27 '16 at 13:06
  • There seems to be some restrictions on when you can use `DynamicResource`, i think you are only allowed to use it in compiled resources, like `Window.Resources` if `Window` is your XAML root element. If everything fails you can write your own markup extension and see if you can implement the desired behaviour. – H.B. Jun 27 '16 at 15:19
  • You also don't seem to need to reference using `DynamicResource` here. – H.B. Jun 27 '16 at 15:21
0

Try this:

<StackPanel Height="40" Orientation="Horizontal">
        <StackPanel.Resources>
            <Style x:Key="GenderButtonStyle" TargetType="{x:Type Button}">
                <Setter Property="MinWidth" Value="100" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type Button}">
                            <Border x:Name="InternalBorder"
                                    CornerRadius="5"
                                    Padding="5">
                                <TextBlock x:Name="InternalText"
                                           HorizontalAlignment="Center"
                                           VerticalAlignment="Center"
                                           Text="{TemplateBinding Content}" />
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger Property="Tag" Value="Male">
                                    <Setter TargetName="InternalBorder" Property="Background" Value="RoyalBlue" />
                                    <Setter TargetName="InternalText" Property="Foreground" Value="White" />
                                </Trigger>
                                <Trigger Property="Tag" Value="Female">
                                    <Setter TargetName="InternalBorder" Property="Background" Value="White" />
                                    <Setter TargetName="InternalBorder" Property="BorderBrush" Value="RoyalBlue" />
                                    <Setter TargetName="InternalBorder" Property="BorderThickness" Value="1,1,1,1" />
                                    <Setter TargetName="InternalText" Property="Foreground" Value="RoyalBlue" />
                                </Trigger>
                                <Trigger Property="IsMouseOver" Value="True">
                                    <!-- Whatever you want -->
                                </Trigger>
                                <Trigger Property="IsPressed" Value="True">
                                    <!-- Whatever you want -->
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </StackPanel.Resources>
        <Button x:Name="MaleButton"
                Content="Male"
                Style="{StaticResource GenderButtonStyle}"
                Tag="Male" />
        <Button x:Name="FemaleButton"
                Margin="5,0,0,0"
                Content="Female"
                Style="{StaticResource GenderButtonStyle}"
                Tag="Female" />
    </StackPanel>

I utilized the sharing capabilities of styles to affect two buttons at the same time rather than repeating clunky code. Then inside the style of these buttons, I've taken control of the template and written my own one to look similar to what you're after.

This style can now be housed in a dictionary if you want.

Logan
  • 806
  • 8
  • 17