Проверьте наличие измененных свойств в привязке WPF MVVM - PullRequest
0 голосов
/ 25 апреля 2018

Я связываю свойства с таким объектом:

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

View

<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, я хотел бы проверить, изменилось ли какое-либо свойство, чтобы я мог сначала попросить пользователя сохранить.

Итак, моей первой мыслью было добавить логическое значение, которое превращается в true при любом изменении, чтобы я мог проверить это в установщике MyModel. Но в настоящее время я не получаю уведомление о MyModel, когда я изменяю свойство, даже если оно происходит в фоновом режиме.

В общем, я понял, потому что MyModel на самом деле не меняется ... но как мне обнаружить какое-либо изменение в любом свойстве?

Заранее спасибо! :)


Ответ:

Чтобы проверить, совпадает ли текущий MyModel со старым, вам нужно сохранить копию этого объекта, чтобы иметь возможность сравнивать их, как описано в Bijington здесь

Для этого вы можете сделать это вручную или использовать бинарный сериализатор, чтобы вы могли клонировать свой мобъект.

вручную:

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

1 Ответ

0 голосов
/ 25 апреля 2018

Я немного изменил свой подход по сравнению с первоначальным комментарием.Вместо реализации 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;
            }
        }
    }
}
...