代码之家  ›  专栏  ›  技术社区  ›  Inferis

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

  •  17
  • Inferis  · 技术社区  · 17 年前

    是否有方法重新定义/别名现有的 SolidColorBrush (实际上是其他资源)?

    举个例子:我在一个外部资源字典中有一个画笔,我想用我自己的键而不是原始键来引用它。我不想依赖于外部引用,因为实际画笔在将来很容易更改。

    3 回复  |  直到 17 年前
        1
  •  14
  •   Tim Cooper    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>
    

    我不想依赖于你 外部参考,因为实际 画笔在颜色上容易变化 将来

        2
  •  4
  •   Ruedi Steinmann    14 年前

    您可以尝试使用StaticResourceExtension,但在全局资源字典中这不起作用(奇怪的编译器和运行时错误):

    <ResourceDictionary 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
    
        <SolidColorBrush x:Key="StatusColor_OK" Color="#ff32a248" />
        <StaticResourceExtension
            x:Key="AliasKey"
            ResourceKey="StatusColor_Error" />
    </ResourceDictionary>
    

    为了克服这个问题,我创建了以下类:

    /// <summary>
    /// Defines an Alias for an existing resource. Very similar to 
    /// <see cref="StaticResourceExtension"/>, but it works in
    ///  ResourceDictionaries
    /// </summary>
    public class Alias: System.Windows.Markup.MarkupExtension
    {
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            IRootObjectProvider rootObjectProvider = (IRootObjectProvider)
                serviceProvider.GetService(typeof (IRootObjectProvider));
            if (rootObjectProvider == null) return null;
            IDictionary dictionary =  rootObjectProvider.RootObject as IDictionary;
            if (dictionary == null) return null;
            return dictionary[ResourceKey];
        }
    
    
        public object ResourceKey { get; set; }
    }
    

    用法:

    <ResourceDictionary 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
    
        <SolidColorBrush x:Key="StatusColor_OK" Color="#ff32a248" />
        <Alias
            x:Key="AliasKey"
            ResourceKey="StatusColor_Error" />
    </ResourceDictionary>
    
        3
  •  3
  •   Community Mohan Dere    8 年前

    我有最新消息要告诉你 Ruedi's

    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;
        }
    }
    

    用法与上面类似,但关键是使用 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>
    

    <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>