【问题标题】:Binding a datacontext string property to a StaticResource key将 datacontext 字符串属性绑定到 StaticResource 键
【发布时间】: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>

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

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

谢谢

【问题讨论】:

    标签: wpf data-binding binding static-resource


    【解决方案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}}" />
    

    这里的主要变化是:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-30
      • 2012-01-29
      • 2020-03-25
      • 2013-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多