Обновление модели из модели вида


Обновить модель из модели вида

Я прочитал какой-то пост о MVVM, но я не уверен, что понимаю способ, которым модель представления обновляет модель

В настоящее время у меня есть два текстовых поля в пользовательском интерфейсе, которые привязаны к представлению XAML и вызывают модель представления при возникновении события . когда должно быть место в модели представления при обновлении модели?

Это модель вида

class ViewModel:INotifyPropertyChanged
    {

 private String _url;
 private String _TemplateType;

    public string URL
    {
    get { return _url;  }
        set
        {
            if (value != _url)
            {
                _url= value;
                OnPropertyChanged("URL");
            }
        }
    }

    public string TemplateType
    {
    get { return _TemplateType;  }
        set
        {
            if (value != _TemplateType)
            {
                _TemplateType= value;
                OnPropertyChanged("URL");
            }
        }
    }

Модель

internal class DefineAddinModel
{
    public string TemplateType { get; set; }
    public String URL { get; set; }
}
4 2

4 ответа:

ViewModel обычно действует как оболочка вокруг модели и содержит ссылку на модель, которая может обновляться либо в ответ на команды, либо автоматически в установщиках свойств.

Обновление: Вот пример того, как виртуальная машина действует как оболочка вокруг модели. Это может показаться бесполезным в вашем примере, но вы обнаружите, что во многих случаях геттеры/сеттеры виртуальной машины должны выполнять какое-то преобразование значений, а не просто передавать их.

class ViewModel:INotifyPropertyChanged
{
 private DefineAddinModel model;

    public string URL
    {
        get { return model.URL;  }
        set
        {
            if (value != model.URL)
            {
                model.url = value;
                OnPropertyChanged("URL");
            }
        }
    }

    public string TemplateType
    {
        get { return model.TemplateType;  }
        set
        {
            if (value != model.TemplateType)
            {
                model.TemplateType = value;
                OnPropertyChanged("TemplateType");
            }
        }
    }

Лучший способ обновить модель - это использовать событие, его безопаснее, поэтому выберите погоду с помощью нажатия кнопки или потерянного фокуса, или все, что вы хотите

void button_click(object sender,eventsarg e)
{
    MyObj.URL = App.Locator.MyVM.MyDefineAddinModel.URL;// App.Locator because MVVMLight is tagged
    MyObj.TemplateType = App.Locator.MyVM.MyDefineAddinModel.TemplateType ;

}

Но лично я использую следующие шаги:

1- в вашей ViewModel создайте объект CurrentItem типа DefineAddinModel и без OnPropertyChanged затем свяжите его с представлением(UI) DataContext корневого элемента на представлении)

2- для модели я использую INotifyPropertyChanged для каждого propery

3- после привязки datacontext вашего корневого элемента к CurrentItem вашего ViewModel затем привязать только URL и TemplateType Свойства к элементам управления, так что любые изменения в текстовом поле обновит CurrentItem свойства

Вы также можете выбрать тип привязки (on LostFocus, или OnPropertyChanged)

Вам нужно привязать текстовые поля к двум свойствам URL и TemplateType. Попробуйте использовать CommandsViewModel)вместо events (в CodeBehind), так как вы находитесь в MVVM. Для обновления модели: используйте кнопку с ее командным свойством, привязанным к OnSave, как в этом примере:

    private String _url;
    private String _TemplateType;
    private DefineAddinModel _defineAddin;

    public DefineAddinModel DefineAddin
    {
        get {return _defineAddin;}
        set
        { 
            _defineAddin = value;
            OnPropertyChanged("DefineAddin");
        }
    }

    public string URL
    {
        get { return _url;  }
        set
            {
                if (value != _url)
                {
                    _url= value;
                    OnPropertyChanged("URL");
                }
            }
    }

    public string TemplateType
    {
        get { return _TemplateType;  }
        set
        {
            if (value != _TemplateType)
            {
                _TemplateType= value;
                OnPropertyChanged("URL");
            }
        }
    }

    public RelayCommand OnSaved
    {
            get;
            set;
    }


    public ViewModel()
    {
        DefineAddin = new DefineAddinModel();
            OnSaved = new RelayCommand(()=>
                              {
                                    DefineAddin.URL  = URL  ;
                                    DefineAddin.TemplateType = TemplateType;
                              });

Подумайте об использовании третьих лиц, таких как MVVMLight это очень помогает вам с MVVM и помощниками вокруг него (команды, Messenger, ViewModelLocator ...)

Я думаю, что правильный ответ здесь- "это зависит".

В большинстве общих случаев преимущество фактического использования ViewModel также заключается в отслеживании "переходного состояния", т. е. состояния операции "редактирование в процессе".

В этом конкретном случае вы бы Не отправляли свои изменения непосредственно в модель каждый раз, когда значение обновляется, вместо этого вы сделали бы это с помощью реализации ICommand 'Update', которая соберет все данные из ViewModel и отправит их вниз в модель. Модель.

Этот подход дает вам много преимуществ:

    Пользователь представления может менять свое мнение столько раз, сколько захочет, и только тогда, когда он будет доволен, модель действительно обновится с их окончательным выбором
  1. это значительно снижает нагрузку на вашу службу сохраняемости, так как только окончательные изменения протолкнуты.
  2. это позволяет выполнять окончательную проверку на полном наборе значений, а не переходных состояниях, и, следовательно, сокращает Программирование сложность и накладные расходы.
  3. Это также делает ваш пользовательский интерфейс гораздо более гибким, так как все приведенные выше примеры подталкивают обновления на Диспетчер пользовательского интерфейса, и позволяет избежать необходимости обслуживать это с помощью задач или других асинхронных подходов.
  4. Резервная модель никогда не находится в несогласованном состоянии, поскольку я бы предположил, что все значения в одном представлении/ViewModel связаны и имеют смысл только при обновлении вместе с использованием кислотного подхода.
Вот пример того, как бы я это сделал.
public class ViewModel:INotifyPropertyChanged {

    private String _url;
    private String _TemplateType;

    public ViewModel(){
        UpdateCommand = new DelegateCommand(OnExecuteUpdate, OnCanExecuteUpdate);
    }

    public bool OnCanExecuteUpdate(object param){
        // insert logic here to return true when one can update
        // or false when data is incomplete
    }

    public void OnExecuteUpdate(object param){
        // insert logic here to update your model using data from the view model
    }

    public ICommand UpdateCommand { get; set;}

    public string URL{
        get { return _url;  }
        set {
            if (value != _url) {
                _url= value;
                OnPropertyChanged("URL");
            }
        }
    }

    public string TemplateType {
        get { return _TemplateType;  }
        set {
            if (value != _TemplateType) {
                _TemplateType= value;
                OnPropertyChanged("TemplateType");
            }
        }
    }

    ... etc.
}

public class DelegateCommand : ICommand {
    Func<object, bool> canExecute;
    Action<object> executeAction;

    public DelegateCommand(Action<object> executeAction)
        : this(executeAction, null) {}

    public DelegateCommand(Action<object> executeAction, Func<object, bool> canExecute) {
        if (executeAction == null) {
            throw new ArgumentNullException("executeAction");
        }
        this.executeAction = executeAction;
        this.canExecute = canExecute;
    }

    public bool CanExecute(object parameter) {
        bool result = true;
        Func<object, bool> canExecuteHandler = this.canExecute;
        if (canExecuteHandler != null) {
            result = canExecuteHandler(parameter);
        }

        return result;
    }

    public event EventHandler CanExecuteChanged;

    public void RaiseCanExecuteChanged() {
        EventHandler handler = this.CanExecuteChanged;
        if (handler != null) {
            handler(this, new EventArgs());
        }
    }

    public void Execute(object parameter) {
        this.executeAction(parameter);
    }
}