将数据上下文字符串属性绑定到 StaticResource 键

问题描述 投票:0回答:3

我有一个带有 ResourceKey 和 Caption 的列表值,这些值都是字符串。 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>

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

我对替代方案持开放态度,我知道仅拥有图像并设置源属性可能会更容易。

谢谢

wpf data-binding binding static-resource
3个回答
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}}" />

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. 转换器是上下文感知的,因此它不仅会查找应用程序的资源,还会查找本地资源(当前窗口、用户控件或页面等)。


0
投票

我无法计算我花了多少时间来解决这个问题。该网站和整个互联网上提出的所有其他解决方案都无法绑定到静态资源以获取

<ImageBrush ImageSource=""/>

https://stackoverflow.com/a/36641146/6373196

这是唯一真正有效的方法,该网站不会让我对此答案进行投票或评论,但我需要说,我真的很感谢 hillin 在这里给出的这个答案!

© www.soinside.com 2019 - 2024. All rights reserved.