Is there a way to redefine/alias an existing SolidColorBrush
(or any other resource, actually)?
Case in point: I have a brush in an external ResourceDictionary that I want to reference by my own key instead of the original key. I don't want to be dependent on the external reference, since the actual brush is prone to change in the future.
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<SolidColorBrush x:Key="SomeExternalResource">Red</SolidColorBrush>
</Window.Resources>
<Grid>
<Grid.Resources>
<StaticResourceExtension ResourceKey="SomeExternalResource" x:Key="SomeAliasedResource"/>
</Grid.Resources>
<Border Background="{StaticResource SomeAliasedResource}"/>
</Grid>
</Window>
I don't want to be dependent on the external reference, since the actual brush is prone to change in the future.
You'll still be dependent on the external resource, just not in as many places.
I have an update to Ruedi's solution. This works for resources both within the same resource dictionary and anywhere within the application.
public class Alias : MarkupExtension
{
public string ResourceKey { get; set; }
public Alias()
{
}
public Alias(string resourceKey)
{
ResourceKey = resourceKey;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return _ProvideLocalValue(serviceProvider) ?? _ProvideApplicationValue();
}
private object _ProvideLocalValue(IServiceProvider serviceProvider)
{
var rootObjectProvider = (IRootObjectProvider)
serviceProvider.GetService(typeof(IRootObjectProvider));
if (rootObjectProvider == null) return null;
var dictionary = rootObjectProvider.RootObject as IDictionary;
if (dictionary == null) return null;
return dictionary.Contains(ResourceKey) ? dictionary[ResourceKey] : null;
}
private object _ProvideApplicationValue()
{
var value = Application.Current.TryFindResource(ResourceKey);
return value;
}
}
The usage is similar to above, but the key is to use Alias
as the markup extension where used, not StaticResource
. Somewhere in the application resource stack, define the resources...
<Application x:Class="WPF.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:wpf="clr-namespace:WPF"
StartupUri="MainWindow.xaml">
<Application.Resources>
<system:String x:Key="Text">Display some text.</system:String>
<system:String x:Key="Other">4</system:String>
<wpf:Alias x:Key="Alias" ResourceKey="Text"/>
<wpf:Alias x:Key="Second" ResourceKey="Other"/>
</Application.Resources>
</Application>
And wherever you're referencing the aliases...
<Window x:Class="WPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpf="clr-namespace:WPF"
Title="MainWindow" Height="150" Width="300">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Text="{wpf:Alias Alias}"/>
<TextBlock Text="{wpf:Alias Second}"/>
</StackPanel>
</Window>
My solution required referencing strings, but it works for any object you want to alias.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With