【发布时间】:2012-02-12 05:46:18
【问题描述】:
我目前正在编写一个图像查看器控件,它封装了 WPF 图像控件和其他内容(用于应用过滤器和更改视图的控件)。这是控件源代码的相关部分:
public partial class ImageViewPort : UserControl, INotifyPropertyChanged
{
private BitmapSource _source;
public static readonly DependencyProperty ImageDescriptorSourceProperty =
DependencyProperty.Register("ImageDescriptorSource",
typeof(ImageDescriptor),
typeof(ImageViewPort),
new UIPropertyMetadata(ImageDescriptorSourceChanged));
public ImageDescriptor ImageDescriptorSource
{
get { return (ImageDescriptor)GetValue(ImageDescriptorSourceProperty); }
set { SetValue(ImageDescriptorSourceProperty, value); }
}
public BitmapSource Source //the image control binds to this beauty!
{
get { return _source; }
set { _source = value; OnPropertyChanged("Source"); }
}
public ImageViewPort() { InitializeComponent(); }
private static void ImageDescriptorSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ImageViewPort viewPort = (ImageViewPort)d;
if (viewPort != null)
{
viewPort.TransformImage();
}
}
private BitmapSource TransformImage()
{
//do something that sets the "Source" property to a BitmapSource
}
}
用户控件的 XAML 代码(仅相关部分):
<UserControl x:Name="viewPort">
<Image Source="{Binding ElementName=viewPort,Path=Source}"/>
</UserControl>
最后是用法:
<WPF:ImageViewPort ImageDescriptorSource="{Binding Path=CurrentImage}"/>
在我的窗口中,我基本上迭代了一个 Collection,并且在我这样做的同时,为 CurrentImage 属性抛出 PropertyChanged 通知。这有效,每次都会调用 getter,因此绑定似乎有效。
我现在期望发生的是我的 UserControl 的 PropertyChanged-Callback 被触发,但没有发生这样的事情(它从不介入,我尝试过使用断点)。我已经尝试过绑定原始类型 (int) 的相同方法,并且成功了。
您在我的实现中发现任何缺陷吗?为什么用户控件不更新? 非常感谢您的帮助!
干杯
塞比
【问题讨论】:
-
检查输出...您是否收到任何绑定警告?您是否还设置了新值? WPF 知道您何时尝试设置已设置的值并忽略它。我建议将 Metadata 类型转换为 FrameworkPropertyMetadata 并提供适当的默认值。
-
这个
{Binding ElementName=viewPort,Path=Source}会暗示你的viewPort元素有SourceDP,这似乎不是这样,那是你实际使用的XAMl 吗? -
@dowhilefor : 忘记控制台窗口中的数据绑定异常是多么愚蠢 :) 谢谢!
-
@Dmitry :我认为 CLR 属性就足够了,否则所有视图模型都必须将其成员实现为 DP...
-
@Sebastian Edelmeier 是真的。它适用于大多数场景。您的 CLR setter 永远不应被调用,它纯粹作为 DP 之上的虚拟外观存在。为了让您的 PropertyChanged 事件被解雇,您必须设置您的 DP - 这永远不会发生。检查您的 Source CLR 属性 - 它不会触发任何影响您的 DP 的操作。为此,您必须调用 this.SetValue(DP, value)。
标签: wpf data-binding user-controls dependency-properties