C# 数据绑定不适用于用户控件';具有依赖项属性的自定义属性(输出窗口是干净的)
注意:与StackOverflow上的其他类似文章一样,我对用户控件内部的控件没有问题,我对用户控件本身的属性有问题。我正在制作一个基于画布的自定义控件,带有一个依赖项属性(使用propdb模板): 在我的页面中,我使用控件并绑定该属性: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
<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
,所以我根本不知道这一点。