我正在研究一个系统,用户可以通过GUI编辑现有对象(“精确地过滤”域对象)。作为UI提示,我们只想在用户真正修改对象的内容时启用保存按钮。我想知道是否有人对这个问题有任何经验,以及采用这种方法的最佳方法。
我正在考虑向域对象添加一个isDirty()标志。当用户开始编辑过滤器时,我会制作一份副本,将其传递给GUI并让用户对副本进行修改。然后,对isDirty()标志的绑定将启用/禁用保存按钮。在保存时,差异将合并到原始对象中并保持不变。
另外,我在想如果用户撤消他对某个对象所做的更改会发生什么。然后isDirty()标志应返回false。所以我想实现这一目标的唯一方法是将每个属性的原始值保留在域对象中。
有什么想法吗?
答案 0 :(得分:3)
正确!
此外,您可以公开两种方法: BeginEdit - 在此方法中,将IsDirty Flag标记为True。意思是你正在修改。当您即将进行修改时调用此方法
CancelEdit - 在此方法中,将IsDirty Flag重置为False。这意味着您已经保留了编辑过程并恢复到原始状态。取消任何修改时调用此方法。
一旦任何修改持续存在,您还会将IsDirty Flag重置为False。
我希望这会有所帮助。
答案 1 :(得分:2)
如果您使用的是.NET框架,您可能需要查看Rockford Lhotka的CSLA .NET框架:http://www.lhotka.net/cslanet/Default.aspx
CSLA是一个成熟的框架,包括对象状态管理(IsDirty),撤消功能,数据绑定等等,还有免费和开源的。
答案 2 :(得分:2)
您可以实现几个有助于更改跟踪和撤消的接口: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;
}
}
}
答案 3 :(得分:1)
如果你有一组正在编辑的对象,那么你可能需要的东西不仅仅是isDirty()的布尔标志。此问题与引用计数没有什么不同,即在编辑时增加脏计数,在撤消时递减。如果你支持撤消我怀疑你最终将会有一些非常多毛的逻辑。我会把它从你的域名对象中删除。
答案 4 :(得分:1)
是的,这很有效。而不是撤消,我使用IsDirty方法来表示某事可能已经改变了记录然后触发了我的“做了记录改变逻辑”。我开发了自己的框架,其中每个表字段实际上都是对象的属性。每次将字段写入对象时,设置“isDirty”标志。在对象的“SaveObject”方法中(实际上它是一个辅助类,但很容易在对象中,但我希望能够以不同的方式保存对象,比如xml,数据库等),我检查了IsDirty和如果它是假的,那么我跳过保存。这简化了逻辑,因为每当我有可能更改对象时,我调用SaveObject并让框架处理它。
答案 5 :(得分:1)
根据您的域,您可以使用相等来测试差异。保留原始对象并制作对象的副本以进行编辑。只要可以执行编辑,就可以适当地修改UI。
此建议的好处是它不会在您的域对象上粘贴GUI特定功能(isDirty()标志),但是YMMV
答案 6 :(得分:1)
如果你支持的操作撤销的粒度级别大于“撤消上次保存后的所有内容”,那么我建议使用撤消堆栈。当编辑某些东西时,它(或它的撤消操作仿函数或委托)被添加到堆栈中。撤消时,只需弹出堆栈并撤消弹出的操作即可。然后,您的isDirty()标志只是检查撤消堆栈是否包含项目,而不是额外的存储和逻辑来更新。