我创建了一个小型用户控件,其中包含一个内容为Image的按钮。我在用户控件上创建了一个“ImageSource”依赖项属性,以便从按钮内的Image绑定到它。
但是在我放置了用户控件设置实例的XAML中,属性在运行时抛出错误:
<ctrl:ImageButton ImageSource="/Resources/Images/Icons/x.png" Command="{Binding Reset}" DisabledOpacity="0.1"/>
并在运行时:
'/ Resources / Images / Icons / x.png'字符串不是'ImageSource'类型的'ImageSource'属性的有效值。 'ImageSource'类型没有公共TypeConverter类。
然后我创建了一个转换器:
public class StringToBitmapImage : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return new BitmapImage(new Uri((string) value, UriKind.RelativeOrAbsolute));
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
然后用它装饰我的依赖属性:
[TypeConverter(typeof(StringToBitmapImage))]
public static readonly DependencyProperty ImageSourceProperty = DependencyProperty.Register(
LambdaHelper.GetMemberName<ImageButton>(ib => ib.ImageSource), typeof (ImageSource), typeof (ImageButton));
[TypeConverter(typeof(StringToBitmapImage))]
public ImageButton ImageSource
{
get { return (ImageButton)GetValue(ImageSourceProperty); }
set { SetValue(ImageSourceProperty, value); }
}
但仍然WPF不会将我的字符串转换为ImageSource(BitmapImage)实例...
怎么办?
答案 0 :(得分:1)
这里有几个不正确的事情:
首先,您的CLR属性返回ImageButton
,而依赖属性定义为ImageSource
。
其次,类型转换器与绑定值转换器不同。您的类型转换器应该来自TypeConverter
并应用于ImageSource
类而不是属性本身。
第三,框架ImageSource
类型已经有TypeConverterAttribute
ImageSourceConverter
作为类型转换器,所以一切都应该开箱即用,而不必编写自定义转换器。确保您没有在另一个命名空间中引用另一个自定义ImageSource
类。
要完成,请使用ImageBrush.ImageSource.AddOwner
而不是重新定义一个全新的依赖项属性。
修改:回答Berryl的评论:
public static readonly DependencyProperty ImageSourceProperty = ImageBrush.ImageSource.AddOwner(typeof(ImageButton);
这段代码将重用现有的ImageSource属性,而不是定义新的(记住每个不同的依赖属性都在全局静态字典中注册),只定义新的所有者和可选的新元数据。它就像OverrideMetadata
,但来自外部阶层。