我如何能实现编辑使用MVVM对象的取消。
例如:我的客户名单。 我选择一个客户的点击按钮“编辑”,一个对话框窗口(的DataContext被绑定到CustomerViewModel)打开,我开始编辑顾客的领域。 然后,我决定要取消编辑,但客户的领域已经被改变了,所以我怎么能在MVVM客户返回到以前的状态?
我如何能实现编辑使用MVVM对象的取消。
例如:我的客户名单。 我选择一个客户的点击按钮“编辑”,一个对话框窗口(的DataContext被绑定到CustomerViewModel)打开,我开始编辑顾客的领域。 然后,我决定要取消编辑,但客户的领域已经被改变了,所以我怎么能在MVVM客户返回到以前的状态?
退房IEditableObject
接口。 你的Customer
类应该实现这一点,你的命令可以执行BeginEdit
/ CancelEdit
/ EndEdit
适当的。
在这篇文章中 ,劳尔只是重新从数据库对象。 我想这是不是解决办法肯特建议少一些麻烦。
internal void Cancel(CustomerWorkspaceViewModel cvm)
{
Mainardi.Model.ObjectMapping.Individual dc = cvm.DataContext
as Mainardi.Model.ObjectMapping.Individual;
int index = 0;
if (dc.ContactID > 0 && dc.CustomerID > 0)
{
index = _customerCollectionViewModel.List.IndexOf(dc);
_customerCollectionViewModel.List[index] =
_customerBAL.GetCustomerById(dc.CustomerID);
}
Collection.Remove(cvm);
}
一个超级简单的方法,如果你的对象是序列化的,比如如果你使用WCF。 您可序列化的原始对象到内部场。 如果,你的对象不是序列化的,那么就使用AutoMapper来创建对象的副本用一行代码。
Order backup = Mapper.Map<Order, Order>(order);
当你处理你的CancelCommand,只需拨打AutoMapper相反。 由于您的属性已经发生变化的通知,什么都行。 其可能的,你可以用IEditableObject结合这些技术,如果您需要和想要编写额外的代码。
您可以使用UpdateSourceTrigger绑定=显式。 在这里 ,你可以找到更多的信息,这可怎么实现的。
我也有这个问题。 我解决了它使用“Memento模式设计”。 有了这个模式,你可以轻松保存原始对象的副本,并在selectedIndexChange
(控制的),或在取消按钮,可以轻松还原您的对象先前的版本。
使用这种模式的一个例子可在如何Memento模式在C#4中实现?
的代码的示例:
如果我们有属性的类用户名密码和NombrePersona我们需要添加方法CreateMemento和SetMemento:
public class Usuario : INotifyPropertyChanged
{
#region "Implementación InotifyPropertyChanged"
internal void RaisePropertyChanged(string prop)
{
if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(prop)); }
}
public event PropertyChangedEventHandler PropertyChanged;
#endregion
private String _UserName = "Capture su UserName";
public String UserName
{
get { return _UserName; }
set { _UserName = value; RaisePropertyChanged("UserName"); }
}
private String _Password = "Capture su contraseña";
public String Password
{
get { return _Password; }
set { _Password = value; RaisePropertyChanged("Password"); }
}
private String _NombrePersona = "Capture su nombre";
public String NombrePersona
{
get { return _NombrePersona; }
set { _NombrePersona = value; RaisePropertyChanged("NombrePersona"); }
}
// Creates memento
public Memento CreateMemento()
{
return (new Memento(this));
}
// Restores original state
public void SetMemento(Memento memento)
{
this.UserName memento.State.UserName ;
this.Password = memento.State.Password ;
this.NombrePersona = memento.State.NombrePersona;
}
然后,我们需要一个类备忘录将包含这样我们的对象的“复制”:
/// <summary>
/// The 'Memento' class
/// </summary>
public class Memento
{
//private Usuario _UsuarioMemento;
private Usuario UsuarioMemento { get; set; }
// Constructor
public Memento(Usuario state)
{
this.UsuarioMemento = new Usuario();
this.State.UserName = state.UserName ;
this.State.Password = state.Password ;
this.State.NombrePersona = state.NombrePersona ;
}
// Gets or sets state
public Usuario State
{
get { return UsuarioMemento; }
}
}
我们需要一个类,将生成并包含我们的纪念对象:
/// <summary>
/// The 'Caretaker' class
/// </summary>
class Caretaker
{
private Memento _memento;
// Gets or sets memento
public Memento Memento
{
set { _memento = value; }
get { return _memento; }
}
}
那么对于实现这种模式 ,我们要创建的实例Caretaker
类
Caretaker creadorMemento = new Caretaker();
而当被选定为编辑一个新的用户,例如创建我们的纪念对象selectedIndexChange
的SelectedUser已经初始化之后,我用事件的方法RaisPropertyChanged
这样的:
internal void RaisePropertyChanged(string prop)
{
if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(prop)); }
if (prop == "RowIndexSelected") // This is my property assigned to SelectedIndex property of my DataGrid
{
if ((this.UserSelected != null) && (creadorMemento .Memento != null))
{
this.UserSelected.SetMemento(creadorMemento .Memento);
}
}
if (prop == "UserSelected") // Property UserSelected changed and if not is null we create the Memento Object
{
if (this.UserSelected != null)
creadorMemento .Memento = new Memento(this.UserSelected);
}
}
对此的解释,当selectedIndexChanged
变化值,我们检查,如果UserSelected
和our memento object
是不是我们在编辑模式下实际项目已经改变,那么我们有方法还原我们的对象null意味着SetMemento
。 如果我们的UserSelected
属性变化,不为空,我们“创造我们的记忆碎片对象”时,编辑是取消,我们将使用。
对于面漆,我们有使用SetMemento
方法在每一个我们需要取消的编辑方法,当编辑在SaveCommand已COMMITED喜欢,我们可以这样设置为null我们的纪念对象this.creadorMemento = null
。
你也可以在你的视图模型模型的状态复制到内部字段,然后揭露这些,然后只将它们在模型中,当用户实际提交更改。
问题可能是,上即时如果验证依赖于被更新的实体审定会更麻烦 - 如果这是一个要求,你可以创建模型的克隆工作,然后合并与实际的实体,当克隆它被保存。
基于假面者velikov的回答 :
您可以标记您的绑定,以通过定义手动更新
<TextBox Name="yourTextBox" Text="{BindingPath=YourBinding, UpdateSourceTrigger=Explicit}" />
在视图(XAML)。 然后,你必须通过调用写在视图模型的UI变化
yourTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource();
当点击保存。
请注意,如果有更新,从别的触发绑定源,他们仍直接在用户界面中。