Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 数据绑定不适用于用户控件';具有依赖项属性的自定义属性(输出窗口是干净的)_C#_Wpf_Data Binding_Custom Controls - Fatal编程技术网

C# 数据绑定不适用于用户控件';具有依赖项属性的自定义属性(输出窗口是干净的)

C# 数据绑定不适用于用户控件';具有依赖项属性的自定义属性(输出窗口是干净的),c#,wpf,data-binding,custom-controls,C#,Wpf,Data Binding,Custom Controls,注意:与StackOverflow上的其他类似文章一样,我对用户控件内部的控件没有问题,我对用户控件本身的属性有问题。我正在制作一个基于画布的自定义控件,带有一个依赖项属性(使用propdb模板): 在我的页面中,我使用控件并绑定该属性: <views:PresentationViewer x:Name="PresentationViewer" PresentationSlide="{Binding CurrentSlide, Mode=TwoWay}" /> 这是我的Ma

注意:与StackOverflow上的其他类似文章一样,我对用户控件内部的控件没有问题,我对用户控件本身的属性有问题。我正在制作一个基于画布的自定义控件,带有一个依赖项属性(使用propdb模板):

在我的页面中,我使用控件并绑定该属性:

    <views:PresentationViewer x:Name="PresentationViewer" PresentationSlide="{Binding CurrentSlide, Mode=TwoWay}" />
这是我的
MainPageViewModel
的代码:

public class MainPageViewModel : INotifyPropertyChanged
{

    // Other codes...

    public ISlide CurrentSlide
    {
        get
        {
            return this.CurrentPresentation?.Slides[this.CurrentSlideIndex];
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void OpenSlide(int index)
    {
        if (index < 0)
        {
            index = 0;
        }

        if (index > this.TotalSlides - 1)
        {
            index = this.TotalSlides - 1;
        }

        this.currentSlideIndexField = index;

        this.PropertyChanged(this, new PropertyChangedEventArgs(nameof(this.CurrentSlideIndex)));

        System.Diagnostics.Debug.WriteLine("Current Slide notified");
        this.PropertyChanged(this, new PropertyChangedEventArgs(nameof(this.CurrentSlide)));

        this.PropertyChanged(this, new PropertyChangedEventArgs(nameof(this.PageCounter)));
    }

}
public类MainPageViewModel:INotifyPropertyChanged
{
//其他代码。。。
公共岛侧幻灯片
{
得到
{
返回此.CurrentPresentation?幻灯片[此.CurrentSlideIndex];
}
}
公共事件属性更改事件处理程序属性更改;
私有void OpenSlide(int索引)
{
如果(指数<0)
{
指数=0;
}
如果(索引>this.TotalSlides-1)
{
index=this.TotalSlides-1;
}
this.currentSlideIndexField=索引;
this.PropertyChanged(this,newpropertyChangedEventArgs(name of(this.CurrentSlideIndex));
System.Diagnostics.Debug.WriteLine(“当前幻灯片已通知”);
this.PropertyChanged(this,newpropertyChangedEventArgs(name of(this.CurrentSlide));
this.PropertyChanged(this,newpropertychangedventargs(name of(this.PageCounter));
}
}
注意我打印属性更改通知的那一行。但是,不会调用用户控件属性的setter或getter。以下是调用
OpenSlide
时的输出(从程序开始输出):

绑定已处于双向模式。我的页面中的其他控件(标签等)也会收到通知并更改其内容,例如页面计数器,因此我猜这也不是ViewModel的问题。我的自定义控件类中是否缺少某些内容?如何使绑定工作?

如中所述,依赖项属性的CLR包装器可能不会被调用,因此不会命中断点,也不会执行
ShowSlideContent
方法。相反,框架直接调用依赖属性的
GetValue
SetValue
方法

因为当前WPF实现的XAML处理器行为 因为属性设置完全绕过包装器,所以不应该 将任何附加逻辑放入包装器的集合定义中 您的自定义依赖项属性。如果你把这样的逻辑放在集合中 定义,则当属性为 在XAML中设置,而不是在代码中设置

为了对更改的属性值做出反应,您必须使用属性元数据注册
PropertyChangedCallback

public ISlide PresentationSlide
{
    get { return (ISlide)GetValue(PresentationSlideProperty); }
    set { SetValue(PresentationSlideProperty, value); }
}

public static readonly DependencyProperty PresentationSlideProperty =
    DependencyProperty.Register(
        nameof(PresentationSlide),
        typeof(ISlide),
        typeof(PresentationViewer),
        new PropertyMetadata(null, PresentationSlidePropertyChanged));

private static void PresentationSlidePropertyChanged(
    DependencyObject o, DependencyPropertyChangedEventArgs e)
{
    ((PresentationViewer)o).ShowSlideContent();
}
或者,使用lambda表达式:

public static readonly DependencyProperty PresentationSlideProperty =
    DependencyProperty.Register(
        nameof(PresentationSlide),
        typeof(ISlide),
        typeof(PresentationViewer),
        new PropertyMetadata(null,
            (o, e) => ((PresentationViewer)o).ShowSlideContent()));
如中所述,依赖项属性的CLR包装器可能不会被调用,因此不会命中断点,也不会执行
ShowSlideContent
方法。相反,框架直接调用依赖属性的
GetValue
SetValue
方法

因为当前WPF实现的XAML处理器行为 因为属性设置完全绕过包装器,所以不应该 将任何附加逻辑放入包装器的集合定义中 您的自定义依赖项属性。如果你把这样的逻辑放在集合中 定义,则当属性为 在XAML中设置,而不是在代码中设置

为了对更改的属性值做出反应,您必须使用属性元数据注册
PropertyChangedCallback

public ISlide PresentationSlide
{
    get { return (ISlide)GetValue(PresentationSlideProperty); }
    set { SetValue(PresentationSlideProperty, value); }
}

public static readonly DependencyProperty PresentationSlideProperty =
    DependencyProperty.Register(
        nameof(PresentationSlide),
        typeof(ISlide),
        typeof(PresentationViewer),
        new PropertyMetadata(null, PresentationSlidePropertyChanged));

private static void PresentationSlidePropertyChanged(
    DependencyObject o, DependencyPropertyChangedEventArgs e)
{
    ((PresentationViewer)o).ShowSlideContent();
}
或者,使用lambda表达式:

public static readonly DependencyProperty PresentationSlideProperty =
    DependencyProperty.Register(
        nameof(PresentationSlide),
        typeof(ISlide),
        typeof(PresentationViewer),
        new PropertyMetadata(null,
            (o, e) => ((PresentationViewer)o).ShowSlideContent()));

精彩的!非常感谢您提供的参考链接。我使用了一篇UWP文章中的
propdb
,所以我根本不知道这一点。太棒了!非常感谢您提供的参考链接。我使用了一篇UWP文章中的
propdb
,所以我根本不知道这一点。