检查 WPF MVVM 绑定中更改的属性

Check for changed properties in WPF MVVM Binding

我正在绑定这样一个对象的属性:

ViewModel:

public class VieModel
{
    public Model MyModel 
    { 
        get
        {
            return myModel;
        } 
        set
        {
            myModel = value;
        }
    }
    private Model myModel
}

型号:

public class Model
{
    public string Name { get; set;}
    public string Info { get; set;}
    public string MoreInfo { get; set;}
}

查看:

<TextBox Text="{Binding MyModel.Name, Mode=TwoWay, Mode=TwoWay, UpdateSourceTrigger=LostFocus }" />
<TextBox Text="{Binding MyModel.Info, Mode=TwoWay, UpdateSourceTrigger=LostFocus }" />
<TextBox Text="{Binding MyModel.MoreInfo, Mode=TwoWay, UpdateSourceTrigger=LostFocus }" />

一切正常,但当 MyModel 发生变化时,我想检查是否有任何 属性 发生变化,以便我可以让用户先保存。

所以我的第一个想法是添加一个布尔值,它在任何更改时都变为真,这样我就可以在 MyModel 的 setter 中检查它。但是目前,当我更改 属性 时,我没有在 MyModel 上收到通知,即使它在后台发生。

总而言之,我明白了,因为 MyModel 并没有真正改变..但是我如何检测任何 属性 上的任何变化?

提前致谢! :)


答案:

要检查当前 MyModel 是否与旧对象相同,您需要存储该对象的副本以便能够按照 Bijington

所述进行比较

为此,您可以手动执行或使用 Binary-Serializer,这样您就可以克隆您的 mobject。

手动:

public class Model
{
    public string Name { get; set;}
    public string Info { get; set;}
    public string MoreInfo { get; set;}

    public static Model Clone(Model obj)
    {
        Model newModel = new Model();

        newModel.Name = obj.Name; 
        newModel.Info = obj.Info; 
        newModel.MoreInfo = obj.MoreInfo; 

        return newModel;
    }
}

BinaryFormatter.Serialize:

Model 中使用的 每个 对象都需要具有 [Serializable] 属性。

[Serializable]
public class Model
{
    public string Name { get; set;}
    public string Info { get; set;}
    public string MoreInfo { get; set;}
    public SecondModel SecondOne { get; set;}

    public static Model Clone(Model obj)
    {
        using (var ms = new MemoryStream())
        {
            var formatter = new BinaryFormatter();
            formatter.Serialize(ms, obj);
            ms.Position = 0;
            return (T)formatter.Deserialize(ms);
        }
    }
}

[Serializable]
public class SecondModel 
{
    public string SecondName { get; set;}
    public string SecondInfo { get; set;}
    public string SecondMoreInfo { get; set;}
}

我对最初的评论略微改变了我的方法。我选择的不是实施 IComparer,而是覆盖 Equals 方法。

public class Model
{
    public string Name { get; set; }
    public string Info { get; set; }
    public string MoreInfo { get; set; }

    public override bool Equals(object obj)
    {
        if (obj is Model model)
        {
            return string.Equals(this.Name, model.Name, StringComparison.Ordinal);
            // && Add your other property comparisons here...;
        }

        return false;
    }

    public override int GetHashCode()
    {
        // You really should provide your implementation here:
        return base.GetHashCode();
    }
}

然后,一旦像上面那样设置了模型 class,您就可以在 ViewModel 中进行检查 class:

public class VieModel
{
    private Model myModel;

    public Model MyModel
    {
        get
        {
            return myModel;
        }
        set
        {
            if (myModel?.Equals(value) != true)
            {
                // The model has changed so you can perform what you want here...


                myModel = value;
            }
        }
    }
}