具有自定义类型依赖属性的用户控件(绑定)

发布于 2024-12-27 13:41:50 字数 1989 浏览 3 评论 0原文

我目前编写了一个图像查看器控件,它封装了 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),并且成功了。

您发现我的实施有任何缺陷吗?为什么用户控件不更新? 预先非常感谢您的帮助!

干杯

塞比

I currently write an image viewer control that encapsulates a WPF Image Control and further stuff (Controls for applying filters and changing views). Here's the relevant portion of control's source code:

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
    }
}

The XAML Code (only relevant parts) of the user control:

<UserControl x:Name="viewPort">
<Image Source="{Binding ElementName=viewPort,Path=Source}"/>
</UserControl>

And finally the usage:

<WPF:ImageViewPort ImageDescriptorSource="{Binding Path=CurrentImage}"/>

In my window, I basically iterate a Collection and, as I do so, throw PropertyChanged notification for the CurrentImage property. That works, the getter is called each time, so the binding seems to work.

What I would expect to happen now is that the PropertyChanged-Callback of my UserControl is fired, but no such thing happens (It never steps in there, I've tried using breakpoints). I've tried the same thing binding a primitive type (int), and that worked.

Do you see any flaw in my implementation? Why isn't the user control updating?
Thanks a lot in advance for any help!

Cheers

Sebi

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

两仪 2025-01-03 13:41:50

检查输出...您收到任何绑定警告吗?您还设置新值吗? WPF 知道您何时尝试设置已设置的值并忽略它。我建议将元数据类型更改为 FrameworkPropertyMetadata 并提供适当的默认值。

要赋予此“注释”更多价值:在绑定上添加“PresentationTraceSources.TraceLevel=High”会提供有关绑定如何尝试获取其值的更多信息,这也有很大帮助,可以发现对 WPF 来说不是错误的问题。

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

Check the output ... do you get any binding warnings? Also are you setting a new value? WPF knows when you try to set a value that is already set and ignores it. I would suggest thange the Metadata type to FrameworkPropertyMetadata and supply a proper default value.

To give this "comment" more value: Adding "PresentationTraceSources.TraceLevel=High" on the binding gives alot more information about how the binding tries to get its value, which also helps alot, finding problems that are not errors for WPF.

<TextBox Text="{Binding MyText, PresentationTraceSources.TraceLevel=High}"/>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文