【发布时间】:2013-05-19 08:41:31
【问题描述】:
这个问题已经让人头疼了一段时间,它阻碍了项目的推进。考虑一个 WPF XAML 表单,其中控件绑定到 ViewModel。 (我正在使用 Caliburn.Micro MVVM 框架和实体框架来处理数据)。 Shell 调用 Initialize() 方法从数据库加载表单数据并设置 PropertyChanged 事件处理程序。有一个IsDirty 标志来跟踪表单中是否有更改的数据。 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,并且启用了 Save 按钮,即使表单刚刚加载并且用户没有更改任何内容。我错过了什么?当然,这是一个常见问题,但我一直无法找到一个好的解决方案。这是我的第一个 MVVM 项目,所以我完全有可能遗漏了一些基本概念。
更新: 澄清一下,我认为问题在于我需要能够挂钩在所有绑定完成更新时将触发的事件或回调,因此我可以连接启动 PropertyChanged 事件处理程序。
【问题讨论】:
-
我知道这个问题很久以前就被问过了,你现在可能已经解决了。我认为我可能对您的问题有解决方案,但是您提供给我的代码示例中没有足够的代码来确定。您是否有任何在代码隐藏中处理的事件会更改这些属性的值(包括 XAML 中的事件)?如果是这样,那么您可以在更新对象中的属性之前检查相关控件的 IsLoaded 属性以查看绑定是否已完成。还有一个 Loaded 事件,用于在绑定完成时触发的控件。
-
有一个关于这种情况的XKCD卡通; redtetrahedron - 你解决了吗?我现在面临同样的问题....
标签: c# wpf mvvm caliburn.micro