如何取消编辑使用MVVM一个对象?(How to cancel an edit to an obje

2019-06-25 06:15发布

我如何能实现编辑使用MVVM对象的取消。

例如:我的客户名单。 我选择一个客户的点击按钮“编辑”,一个对话框窗口(的DataContext被绑定到CustomerViewModel)打开,我开始编辑顾客的领域。 然后,我决定要取消编辑,但客户的领域已经被改变了,所以我怎么能在MVVM客户返回到以前的状态?

Answer 1:

退房IEditableObject接口。 你的Customer类应该实现这一点,你的命令可以执行BeginEdit / CancelEdit / EndEdit适当的。



Answer 2:

在这篇文章中 ,劳尔只是重新从数据库对象。 我想这是不是解决办法肯特建议少一些麻烦。

    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);
    }


Answer 3:

一个超级简单的方法,如果你的对象是序列化的,比如如果你使用WCF。 您可序列化的原始对象到内部场。 如果,你的对象不是序列化的,那么就使用AutoMapper来创建对象的副本用一行代码。

Order backup = Mapper.Map<Order, Order>(order);

当你处理你的CancelCommand,只需拨打AutoMapper相反。 由于您的属性已经发生变化的通知,什么都行。 其可能的,你可以用IEditableObject结合这些技术,如果您需要和想要编写额外的代码。



Answer 4:

您可以使用UpdateSourceTrigger绑定=显式。 在这里 ,你可以找到更多的信息,这可怎么实现的。



Answer 5:

我也有这个问题。 我解决了它使用“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变化值,我们检查,如果UserSelectedour memento object是不是我们在编辑模式下实际项目已经改变,那么我们有方法还原我们的对象null意味着SetMemento 。 如果我们的UserSelected属性变化,不为空,我们“创造我们的记忆碎片对象”时,编辑是取消,我们将使用。

对于面漆,我们有使用SetMemento方法在每一个我们需要取消的编辑方法,当编辑在SaveCommand已COMMITED喜欢,我们可以这样设置为null我们的纪念对象this.creadorMemento = null



Answer 6:

你也可以在你的视图模型模型的状态复制到内部字段,然后揭露这些,然后只将它们在模型中,当用户实际提交更改。

问题可能是,上即时如果验证依赖于被更新的实体审定会更麻烦 - 如果这是一个要求,你可以创建模型的克隆工作,然后合并与实际的实体,当克隆它被保存。



Answer 7:

基于假面者velikov的回答 :

您可以标记您的绑定,以通过定义手动更新

<TextBox Name="yourTextBox" Text="{BindingPath=YourBinding, UpdateSourceTrigger=Explicit}" />

在视图(XAML)。 然后,你必须通过调用写在视图模型的UI变化

yourTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource();
当点击保存。

请注意,如果有更新,从别的触发绑定源,他们仍直接在用户界面中。



文章来源: How to cancel an edit to an object using MVVM?
标签: wpf mvvm