在WPF中重新定义/别名资源?

Inf*_*ris 17 wpf resources

有没有办法重新定义/别名现有SolidColorBrush(或任何其他资源,实际上)?

举个例子:我在外部ResourceDictionary中有一个画笔,我想用自己的键而不是原始键来引用它.我不想依赖外部参考,因为实际的刷子将来很容易改变.

Ken*_*art 14

<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>
Run Code Online (Sandbox Code Playgroud)

我不想依赖外部参考,因为实际的刷子将来很容易改变.

您仍将依赖外部资源,而不是在很多地方.

  • 这不适合我.我得到<<类型的对象"System.Windows.StaticResourceExtension"不能应用于期望类型"System.Windows.Media.Brush">>的属性. (5认同)

gre*_*nis 6

我有Ruedi解决方案的更新。这适用于同一资源字典中的资源以及应用程序中任何位置的资源。

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

用法与上面类似,但关键是Alias使用时作为标记扩展,而不是StaticResource. 在应用程序资源堆栈中的某个位置,定义资源...

<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>
Run Code Online (Sandbox Code Playgroud)

无论您在何处引用别名...

<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>
Run Code Online (Sandbox Code Playgroud)

我的解决方案需要引用字符串,但它适用于您想要别名的任何对象。