我编写了以下标记扩展,以允许在一般情况下绑定到 resourceKey。
using System;
using System.ComponentModel;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
using System.Windows.Markup;
namespace Mersoft.Mvvm.MarkupExtensions
{
public class ResourceBinding : MarkupExtension
{
#region Helper properties
public static object GetResourceBindingKeyHelper(DependencyObject obj)
{
return (object)obj.GetValue(ResourceBindingKeyHelperProperty);
}
public static void SetResourceBindingKeyHelper(DependencyObject obj, object value)
{
obj.SetValue(ResourceBindingKeyHelperProperty, value);
}
public static readonly DependencyProperty ResourceBindingKeyHelperProperty =
DependencyProperty.RegisterAttached("ResourceBindingKeyHelper", typeof(object), typeof(ResourceBinding), new PropertyMetadata(null, ResourceKeyChanged));
static void ResourceKeyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var target = d as FrameworkElement;
var newVal = e.NewValue as Tuple<object, DependencyProperty>;
if (target == null || newVal == null)
return;
var dp = newVal.Item2;
if (newVal.Item1 == null)
{
target.SetValue(dp, dp.GetMetadata(target).DefaultValue);
return;
}
target.SetResourceReference(dp, newVal.Item1);
}
#endregion
public ResourceBinding()
{
}
public ResourceBinding(string path)
{
this.Path = new PropertyPath(path);
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
var provideValueTargetService = (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));
if (provideValueTargetService == null)
return null;
if (provideValueTargetService.TargetObject != null &&
provideValueTargetService.TargetObject.GetType().FullName == "System.Windows.SharedDp")
return this;
var targetObject = provideValueTargetService.TargetObject as FrameworkElement;
var targetProperty = provideValueTargetService.TargetProperty as DependencyProperty;
if (targetObject == null || targetProperty == null)
return null;
var binding = new Binding();
#region binding
binding.Path = this.Path;
binding.XPath = this.XPath;
binding.Mode = this.Mode;
binding.UpdateSourceTrigger = this.UpdateSourceTrigger;
binding.Converter = this.Converter;
binding.ConverterParameter = this.ConverterParameter;
binding.ConverterCulture = this.ConverterCulture;
if (this.RelativeSource != null)
binding.RelativeSource = this.RelativeSource;
if (this.ElementName != null)
binding.ElementName = this.ElementName;
if (this.Source != null)
binding.Source = this.Source;
binding.FallbackValue = this.FallbackValue;
#endregion
var multiBinding = new MultiBinding();
multiBinding.Converter = HelperConverter.Current;
multiBinding.ConverterParameter = targetProperty;
multiBinding.Bindings.Add(binding);
multiBinding.NotifyOnSourceUpdated = true;
targetObject.SetBinding(ResourceBindingKeyHelperProperty, multiBinding);
return null;
}
#region Binding Members
public object Source
{
get;
set;
}
public PropertyPath Path
{
get;
set;
}
[DefaultValue(null)]
public string XPath
{
get;
set;
}
[DefaultValue(BindingMode.Default)]
public BindingMode Mode
{
get;
set;
}
[DefaultValue(UpdateSourceTrigger.Default)]
public UpdateSourceTrigger UpdateSourceTrigger
{
get;
set;
}
[DefaultValue(null)]
public IValueConverter Converter
{
get;
set;
}
[DefaultValue(null)]
public object ConverterParameter
{
get;
set;
}
[DefaultValue(null)]
[TypeConverter(typeof(System.Windows.CultureInfoIetfLanguageTagConverter))]
public CultureInfo ConverterCulture
{
get;
set;
}
[DefaultValue(null)]
public RelativeSource RelativeSource
{
get;
set;
}
[DefaultValue(null)]
public string ElementName
{
get;
set;
}
#endregion
#region BindingBase Members
public object FallbackValue
{
get;
set;
}
#endregion
#region Nested types
private class HelperConverter : IMultiValueConverter
{
public static readonly HelperConverter Current = new HelperConverter();
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return Tuple.Create(values[0], (DependencyProperty)parameter);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
#endregion
}
}
使用方法
<Image Source="{local:ResourceBinding ImageResourceKey}"/>
{DynamicResource {Binding ImageResourceKey}}
。我以前从没见过这个,而且看起来不对,为什么不直接用这个:{Binding ImageResourceKey}
。请展示你的ImageResourceKey
定义。 - Sheridanstring ImageResourceKey { get; set; }
:) - Spook