这个问题已经让人头疼了一段时间,并且阻碍了项目的推进。考虑一个带有绑定(bind)到 ViewModel 的控件的 WPF XAML 窗体。 (我正在为数据使用 Caliburn.Micro MVVM 框架和 Entity Framework )。 shell 调用 Initialize()
方法从数据库加载表单数据并设置 PropertyChanged 事件处理程序。有一个 IsDirty
标志跟踪表单中是否有更改的数据。有一个“保存”按钮绑定(bind)到 IsDirty
属性,以便在数据更改时启用它。
// Sample code; forms have many controls....
// this is the property that the controls are bound to
public Entity BoundData { get; set; }
public void Initialize()
{
// this is an example line where I query the database from the Entity Framework ObjectContext...
BoundData = objectContext.DataTable.Where(entity => entity.ID == 1).SingleOrDefault();
// this is to cause the form bindings to retrieve data from the BoundData entity
NotifyOfPropertyChange("BoundData");
// wire up the PropertyChanged event handler
BoundData.PropertyChanged += BoundData_PropertyChanged;
IsDirty = false;
}
void BoundData_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
IsDirty = true;
}
// implementation of the IsDirty flag
public bool IsDirty
{
get
{
return _isDirty;
}
set
{
_isDirty = value;
NotifyOfPropertyChange("IsDirty");
}
}
问题是 BoundData_PropertyChanged
事件处理程序被命中,因为在 Initialize()
方法完成后从数据库初始化表单。因此,IsDirty
标志设置为 true,并启用“保存”按钮,即使表单刚刚加载并且用户没有更改任何内容。我错过了什么?这当然是一个常见问题,但我一直找不到好的解决方案。这是我的第一个 MVVM 项目,所以我完全有可能遗漏了一些基本概念。
更新:澄清一下,我认为问题是我需要能够连接到一个事件或回调中,当所有绑定(bind)都完成更新时,该事件或回调将触发,这样我就可以连接启动 PropertyChanged 事件处理程序。
最佳答案
您可以做的一件事可能会有所帮助,就是像这样设置触发更改的属性:
public virtual bool Prop1
{
get
{
return _prop1;
}
set
{
if (_prop1 != value)
{
_prop1 = value;
NotifyOfPropertyChange("IsDirty");
}
}
这样,事件只会在值实际更改时触发,而不仅仅是冗余设置。这当然假设在您的情况下该值实际上没有改变。
关于c# - 如何防止 PropertyChanged 在控件初始化时触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16723232/