MVVM : how to make view model set fields of clean model to persist view changes to database

标签 mvvm prism

在具有干净模型(未实现 INotifyPropertyChabged 之类的接口(interface))的 MVVM 应用程序中, View 模型包含绑定(bind)到 View 的属性,这些属性从 View 模型中包含的模型对象获取其值,并且应该在 View 更改时设置其属性的值绑定(bind)到这些属性的控件。
问题是 View 何时改变;更改由绑定(bind) View 模型属性捕获,但属性无法设置模型对象字段,模型不会更改。我需要模型字段接受 View 模型属性的设置,然后考虑到它是一个干净的模型,我可以将更新的模型保存到数据库中。

这里是 View 模型代码的一部分

public class SubsystemDetailsViewModel: INotifyPropertyChanged, ISubsystemDetailsViewModel
    {
        #region Fields
        //Properties to which View is bound
        private int? _serial;
        public int? Serial
        {
            get { return Subsystem.Serial; }
            set
            {
                //Subsystem.Serial=value;
                _serial = value;
                OnPropertyChanged("Serial");
            }
        }

        private string _type;
        public string Type
        {
            get { return Subsystem.Type; }
            set
            {
                //Subsystem.Type = value;
                _type = value;
                OnPropertyChanged("Type");
            }
        }


       //remaining properties ....


        #endregion

        //Service
        private readonly ISubsystemService _subsystemService;



        //Reference to the View
        public ISubsystemDetailsView View { get; set; }

        //Event Aggregator Event
        private readonly IEventAggregator eventAggregator;

        //Commands
        public ICommand ShowTPGCommand { get; set; }
        public DelegateCommand UpdateCommand { get; set; }

       //
        private bool _isDirty;

        //Constructor ************************************************************************************************
        public SubsystemDetailsViewModel(ISubsystemDetailsView View, ISubsystemService subsystemService, IEventAggregator eventAggregator)
        {
            _subsystemService = subsystemService;

            this.View = View;
            View.VM = this;

            //EA-3
            if (eventAggregator == null) throw new ArgumentNullException("eventAggregator");
            this.eventAggregator = eventAggregator;
            //Commands
            this.ShowTPGCommand = new DelegateCommand<PreCommissioning.Model.Subsystem>(this.ShowTestPacks);
            this.UpdateCommand = new DelegateCommand(this.UpdateSubsystem, CanUpdateSubsystem);


        }


        //****************************************************************************************************************
        //ICommand-3 Event Handler 
        //this handler publish the Payload "SelectedSubsystem" for whoever subscribe to this event
        private void ShowTestPacks(PreCommissioning.Model.Subsystem subsystem)
        {
            eventAggregator.GetEvent<ShowTestPacksEvent>().Publish(SelSubsystem);
        }
        //===============================================================================================
        private void UpdateSubsystem()
        {

            _subsystemService.SaveChanges(Subsystem);
        }

        private bool CanUpdateSubsystem()
        {
            return _isDirty;
        }
        //*******************************************************************************************
        public void SetSelectedSubsystem(PreCommissioning.Model.Subsystem subsystem)
        {
            this.SelSubsystem = subsystem;

        }

        //************************************************************************************************************
        /// <summary>
        /// Active subsystem >> the ItemSource for the View
        /// </summary>
        private PreCommissioning.Model.Subsystem _subsystem;
        public PreCommissioning.Model.Subsystem Subsystem
        {
            get
            { 
                //return this._subsystem;
                GetSubsystem(SelSubsystem.SubsystemNo);
                return this._subsystem;

            }

            set
            {
                if (_subsystem != value)
                {
                    _subsystem = value;
                    OnPropertyChanged("Subsystem");
                }

            }

        }



        //Call the Service to get the Data form the Database
        private void GetSubsystem(string SSNo)
        {
            this._subsystem = _subsystemService.GetSubsystem(SSNo);


        }





        #region Implementation of INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propertyName)
        {
            _isDirty = true;
            UpdateCommand.RaiseCanExecuteChanged();

            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion

    }
}

Subsystem 是使用 GetSubsystem() 方法填充的模型对象。像 Serial 这样的 View 模型属性从模型中获取其值,如图所示。我尝试设置模型属性,如属性设置部分中的注释行所示,但子系统对象没有发生变化,始终保持其原始值

最佳答案

如果 GetSubsystem每次都返回一个新的子系统,那是你的问题。在您绑定(bind)到 View 的属性的“集合”中,您调用的是公共(public)属性“子系统”,而不是您创建的私有(private)字段。因此,每次从 View 中设置属性时,您都在调用 Subsystem.get,它调用 GetSubsystem(SelSubsystem.SubsystemNo); .

我认为,在您的 ViewModel 属性中,您希望将其更改为:

//Properties to which View is bound
public int? Serial
{
    get { return _subsystem.Serial; }
    set
    {
        _subsystem.Serial=value; // NOTE THE USE OF THE PRIVATE FIELD RATHER THAN THE PROPERTY
        OnPropertyChanged("Serial");
    }
}

public string Type
{
    get { return _subsystem.Type; }
    set
    {
        _subsystem.Type = value; // NOTE THE USE OF THE PRIVATE FIELD RATHER THAN THE PROPERTY
        OnPropertyChanged("Type");
}

关于MVVM : how to make view model set fields of clean model to persist view changes to database,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14162168/

相关文章:

c# - 字段更改时,MVVM 对象触发属性更改事件

c# - ListView 中的 MVVM 分组项目

javascript - 从 JSON 中抓取树

wpf - 我应该使用MVVM还是仅使用ContentControl加载屏幕?

c# - 绑定(bind) InputBindings 后 TextEdit Binding 变为 null

c# - MVVM 中的模型是做什么用的?

prism - MEF:PRISM 的替代品?

wpf - StockTrader RI > Controller 、演示者、WTF?

c# - MVVM:绑定(bind)到模型,同时使模型与服务器版本保持同步

xamarin.forms - 来自 Android 后台服务的 Prism DI 容器