我正在构建一个使用简单MVVM架构和EF的WPF应用程序。
我看到一个奇怪的问题,如果我尝试设置datetime属性,我得到一个System.StackOverflowException
。如果我没有设置datetime属性,我不会得到例外。
绑定:
<DatePicker Style="{StaticResource Dp}"
Grid.Column="1"
SelectedDate="{Binding Date, UpdateSourceTrigger=PropertyChanged}" />
公共财产:
public DateTime Date
{
get
{
return _criticalDate.Date;
}
set
{
if (_criticalDate != null && value != null && _criticalDate.Date == value)
return;
_criticalDate.Date = value;
OnPropertyChanged("Date");
}
}
尝试使用调试器逐步执行它似乎不起作用。我已经看过所有试图看到发生了什么的东西......关于可能导致这种情况的任何暗示?
这是CriticalDate
类的定义,
public partial class CriticalDate
{
public int ID { get; set; }
public System.DateTime Date { get; set; }
public string CriticalReason { get; set; }
public int FileID { get; set; }
}
_criticalDate
字段是CriticalDate
类的私有实例。 CriticalDate
是EF从我的数据库架构创建的类。它本身不是DateTime
。
最终更新
我仍然不知道出了什么问题......我撕掉了有问题的部分(包括绑定)并从头开始重写。不知道我做了什么不同,但它现在有效。我认为这与物品控制的设置方式有关...如果我有更多的时间(愚蠢的截止日期),我会回去看看它是什么,但现在这是一个谜。
感谢分享我的困惑,如果只是如此简短。
答案 0 :(得分:0)
尝试删除OnPropertyChanged("Date");
,或将绑定模式更改为OneWayToSource
。
来自documentation of UpdateSourceTrigger
。
TwoWay或OneWayToSource的绑定侦听目标属性中的更改并将它们传播回源。这称为更新源。通常,只要目标属性更改,就会发生这些更新。这适用于复选框和其他简单控件,但它通常不适用于文本字段。每次击键后更新都会降低性能,并且在提交新值之前,它会拒绝用户退回并修复键入错误的通常机会。因此,Text属性的默认UpdateSourceTrigger值是LostFocus而不是PropertyChanged。
我相信OnPropertyChanged("Date");
方法上的Date_set
正在更新UI,而UI又会再次调用Date_set
方法,从而完成循环并导致递归。
答案 1 :(得分:0)
编辑:以下内容无用,因为调试器不会显示堆栈溢出的调用堆栈。相反,请查看How to debug a stackoverflowexception in .NET
将Visual Studio调试器设置为在StackOverflowExceptions
上中断并检查callstack。
Ctrl+Alt+E
或
Debug->Exceptions...
点击Find
并输入StackOverflow
,然后选中Thrown
列中的复选框。
您可能会在同一方法或一组方法中进行数百次递归调用。
如果库内发生异常,您可能需要禁用“Just My Code”
答案 2 :(得分:0)
确保在不需要时不更新日期,并打破绑定中的反馈循环。我通常会在我的二传手周围进行检查:
public DateTime Date
{
get
{
return _criticalDate.Date;
}
set
{
if (_criticalDate.Date != value)
{
if (_criticalDate != null && value != null && _criticalDate.Date == value)
return;
_criticalDate.Date = value;
OnPropertyChanged("Date");
}
}
}