将数据上下文字符串属性绑定到静态资源键

11

我有一个包含 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>

我认为我已经尝试了所有的绑定静态资源的排列组合。

我也愿意尝试其他方法,我知道只需要使用一张图片并设置其源属性可能更容易。

谢谢。

2个回答

15
经过一番思考,我最终使用了一个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}}" />

1
使用FindResource而不是索引访问器[]: return Application.Current.FindResource(value);它将在所有资源中搜索,而不仅仅是app.xaml。 - Liero
不知道为什么,但我必须使用_App_.Current.Resources而不是Application.Current.Resources。 - Ronnie W

7

这里我提供了@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}}" />

这里的主要变化是:
  1. 转换器现在是一个System.Windows.Markup.MarkupExtension,因此可以直接使用而不需要声明为资源。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接