【问题标题】:user control with custom type dependency property (Bound)具有自定义类型依赖属性的用户控件(绑定)
【发布时间】: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 元素有Source DP,这似乎不是这样,那是你实际使用的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


【解决方案1】:

检查输出...您是否收到任何绑定警告?您是否还设置了新值? WPF 知道您何时尝试设置已设置的值并忽略它。我建议将 Metadata 类型转换为 FrameworkPropertyMetadata 并提供适当的默认值。

要给这个“评论”更多价值:在绑定上添加“PresentationTraceSources.TraceLevel=High”可以提供更多关于绑定如何尝试获取其值的信息,这也有助于发现不是 WPF 错误的问题.

<TextBox Text="{Binding MyText, PresentationTraceSources.TraceLevel=High}"/>

【讨论】:

  • 感谢,更感谢您添加有关 TraceLevel 的信息 - 这正是我一直在寻找的东西!
猜你喜欢
  • 2012-08-07
  • 1970-01-01
  • 2011-10-19
  • 2012-08-29
  • 2019-05-26
  • 2014-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多