【问题标题】:Check for changed properties in WPF MVVM Binding检查 WPF MVVM 绑定中更改的属性
【发布时间】:2018-04-25 22:13:52
【问题描述】:

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

视图模型

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 的设置器中检查它。但是目前,当我更改属性时,即使它在后台进行,我也没有收到MyModel 的通知..

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

提前致谢! :)


答案:

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

为此,您可以手动完成或使用二进制序列化器,以便克隆您的 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

你需要 EVERY 在你的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;}
}

【问题讨论】:

  • 您究竟何时需要知道MyModel 是否有任何更改?如果它正在更改MyModel 的值,您可以在属性设置器中处理它并提供IComparer 的实现以检查是否有任何更改
  • 您必须实现INotifyPropertyChanged 接口。如此处所示stackoverflow.com/a/49955379/3587031
  • @k1ll3r8e - 正如我所说,绑定运行良好。 ;)
  • @Bijington - 这就是我需要的。从不使用 IComparer。会看看它。或者你能举一个简单的例子吗?会很好! :)
  • @bene_rawr 我添加了一个基本示例,虽然现在不使用 IComparer。

标签: mvvm data-binding inotifypropertychanged


【解决方案1】:

与最初的评论相比,我稍微改变了我的方法。我没有实现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();
    }
}

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

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

【讨论】:

  • 好吧,这有点奏效。谢谢!不得不做一些其他的事情来完成我的场景,但现在它就像一个魅力。
猜你喜欢
  • 2011-11-10
  • 2016-03-28
  • 1970-01-01
  • 2011-01-23
  • 2020-04-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-20
  • 1970-01-01
相关资源
最近更新 更多