将 datacontext 字符串属性绑定到 StaticResource 键

Posted

技术标签:

【中文标题】将 datacontext 字符串属性绑定到 StaticResource 键【英文标题】:Binding a datacontext string property to a StaticResource key 【发布时间】:2010-10-16 06:54:50 【问题描述】:

我有一个带有 ResourceKey 和 Caption 的 List 值,这些值都是字符串。 Resource 是资源字典中定义的实际资源的名称。这些 ResourceKey 图标中的每一个都是 Canvas 的。

<Data ResourceKey="IconCalendar" Caption="Calendar"/>
<Data ResourceKey="IconEmail" Caption="Email"/>

然后我有一个列表视图,其中有一个带有按钮的数据模板和按钮下方的文本标题。我想要做的是将 Resource 静态资源显示为按钮的内容。

<ListView.ItemTemplate>
    <DataTemplate>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>

            <Button Content="Binding ResourceKey" Template="StaticResource  RoundButtonControlTemplate"/>
            <TextBlock Grid.Row="1" Margin="0,10,0,0" Text="Binding Caption" HorizontalAlignment="Center" FontSize="20" FontWeight="Bold" />
        </Grid>
    </DataTemplate>
</ListView.ItemTemplate>

我想我已经尝试了绑定静态资源等的所有排列。

我对替代方案持开放态度,我知道只有一张图片并设置源属性可能更容易。

谢谢

【问题讨论】:

【参考方案1】:

经过一番思考,我最终像这样使用了ValueConvertor

class StaticResourceConverter : IValueConverter

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    
        var resourceKey = (string)value;

        return Application.Current.Resources[resourceKey];
    

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    
        throw new Exception("The method or operation is not implemented.");
    

按钮上的绑定变成了

<Button Content="Binding ResourceKey, Converter=StaticResource resourceConverter" />

【讨论】:

使用 FindResource 代替索引访问器 []: return Application.Current.FindResource(value);它将搜索所有资源,而不仅仅是 app.xaml 不知道为什么,但我不得不使用 App.Current.Resources 而不是 Application.Current.Resources【参考方案2】:

这里我得到了@dvkwong 答案的改进版本(以及@Anatoliy Nikolaev 的编辑):

class StaticResourceConverter : MarkupExtension, IValueConverter

    private Control _target;


    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    
        var resourceKey = (string)value;

        return _target?.FindResource(resourceKey) ?? Application.Current.FindResource(resourceKey);
    

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    
        throw new NotSupportedException();
    

    public override object ProvideValue(IServiceProvider serviceProvider)
    
        var rootObjectProvider = serviceProvider.GetService(typeof(IRootObjectProvider)) as IRootObjectProvider;
        if (rootObjectProvider == null)
            return this;

        _target = rootObjectProvider.RootObject as Control;
        return this;
    

用法:

<Button Content="Binding ResourceKey, Converter=design:StaticResourceConverter" />

这里的主要变化是:

    转换器现在是System.Windows.Markup.MarkupExtension,因此可以直接使用而无需声明为资源。

    转换器是上下文感知的,因此它不仅会查找您应用的资源,还会查找本地资源(当前窗口、用户控件或页面等)。

【讨论】:

以上是关于将 datacontext 字符串属性绑定到 StaticResource 键的主要内容,如果未能解决你的问题,请参考以下文章

DataContext和ItemSource

MVVM + Datacontext + DataTemplate + Blend = 问题

XAML - 绑定到 DataContext 并使用转换器?

如何将命令绑定到 DataContext 之外的按钮中?

上下文菜单绑定到父窗口的 Datacontext

上下文菜单绑定到父窗口的 Datacontext