User interface 对象编辑和isDirty()标志
我正在开发一个系统,用户可以通过GUI编辑现有对象(确切地说是“过滤”域对象)。作为UI提示,我们只希望在用户确实修改了对象的某些内容时启用save按钮。我想知道是否有人有过这个问题的经验,最好的方法是什么 我正在考虑向域对象添加isDirty()标志。当用户开始编辑过滤器时,我会制作一个副本,将其传递给GUI,并让用户对副本进行修改。isDirty()标志上的绑定将启用/禁用保存按钮。保存时,差异将合并到原始对象中并持久化 另外,我在想,如果用户撤消对对象所做的更改,会发生什么情况。isDirty()标志随后应返回false。所以我想实现这一点的唯一方法是将每个属性的原始值保留在域对象中 有什么想法吗?正确 此外,还可以公开两种方法: BeginEdit-在这个方法中,您可以将IsDirty标志标记为True。意思是你在做修改。要进行修改时调用此方法 CancelEdit-在此方法中,将IsDirty标志重置为False。这意味着您已将编辑过程树状化并恢复到原始状态。取消任何修改时调用此方法 一旦任何修改被持久化,您还可以将IsDirty标志重置为FalseUser interface 对象编辑和isDirty()标志,user-interface,dns,flags,User Interface,Dns,Flags,我正在开发一个系统,用户可以通过GUI编辑现有对象(确切地说是“过滤”域对象)。作为UI提示,我们只希望在用户确实修改了对象的某些内容时启用save按钮。我想知道是否有人有过这个问题的经验,最好的方法是什么 我正在考虑向域对象添加isDirty()标志。当用户开始编辑过滤器时,我会制作一个副本,将其传递给GUI,并让用户对副本进行修改。isDirty()标志上的绑定将启用/禁用保存按钮。保存时,差异将合并到原始对象中并持久化 另外,我在想,如果用户撤消对对象所做的更改,会发生什么情况。isDir
我希望这会有所帮助。如果您有一组正在编辑的对象,那么您可能需要的不仅仅是isDirty()的布尔标志。此问题与引用计数相同,即在编辑时增加脏计数,在撤消时减少脏计数。如果你支持撤销,我怀疑你最终会得出一些非常复杂的逻辑。我会将其排除在域对象之外。是的,这很有效。我没有撤消,而是使用IsDirty方法表示可能有什么东西改变了记录,然后触发了我的“记录是否改变了逻辑”。我开发了自己的框架,其中每个表字段实际上都是对象的属性。每次将字段写入对象时,都会设置“isDirty”标志。在对象的“SaveObject”方法中(实际上它是一个helper类,但可以很容易地放在对象中,但我希望能够以不同的方式保存对象,如xml、数据库等),我检查IsDirty,如果它为false,则跳过保存。这简化了逻辑,因为每次我有可能更改对象时,我都调用SaveObject并让框架处理它 如果您使用的是.NET framework,您可能想看看Rockford Lhotka的CSLA.NET framework:
CSLA是一个成熟的框架,包括对象状态管理(IsDirty)、撤消功能、数据绑定等,而且它是免费的、开源的。根据您的领域,您可以使用相等性来测试差异。保留原始对象并复制该对象以进行编辑。任何时候可以执行编辑,适当地修改UI
这个建议的好处是,它不会在您的域对象上粘贴特定于GUI的功能(isDirty()标志),但是YMMV如果您支持的操作撤消的粒度级别大于“自上次保存后撤消所有内容”,那么我建议使用撤消堆栈。编辑某个对象时,它(或其撤消操作函子或委托)将被添加到堆栈中。撤消时,只需弹出堆栈并撤消弹出的操作。然后,您的isDirty()标志只是检查撤消堆栈是否包含项,而不是要更新的额外存储和逻辑。有几个接口可以帮助您实现更改跟踪和撤消:INotifyPropertyChanged和IEditableObject。这两个接口都允许对象很好地进行数据绑定
public class Person : INotifyPropertyChanged, IEditableObject
{
private bool isDirty;
public bool IsDirty
{
get { return isDirty; }
}
private string firstname = string.Empty;
public string Firstname
{
get { return firstname; }
set
{
if (firstname == value) return;
firstname = value;
NotifyPropertyChanged("Firstname");
}
}
private string lastname = string.Empty;
public string Lastname
{
get { return lastname; }
set
{
if (lastname == value) return;
lastname = value;
NotifyPropertyChanged("Lastname");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
isDirty = true;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
private bool inTrans;
private Person copy;
public void BeginEdit()
{
if (!inTrans)
{
if (copy == null)
copy = new Person();
copy.isDirty = isDirty;
copy.Firstname = Firstname;
copy.Lastname = Lastname;
inTrans = true;
isDirty = false;
}
}
public void CancelEdit()
{
if (inTrans)
{
isDirty = copy.isDirty;
Firstname = copy.Firstname;
Lastname = copy.Lastname;
inTrans = false;
}
}
public void EndEdit()
{
if (inTrans)
{
copy = null;
inTrans = false;
}
}
}
谢谢你的建议。我想知道撤销堆栈将位于何处。它是UndoManager中的一个单独对象还是某种类型的对象,堆栈链接到您正在编辑的域对象?谢谢所有的回答。我接受了这个答案,因为这是第一个,得票最多。这听起来很像CSLA。如果您使用的是.NET,我建议您检查一下。