1

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

这里是视图模型代码的一部分

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 这样的视图模型属性从模型中获取其值,如图所示。我尝试设置模型属性,如属性设置部分中的注释行所示,但子系统对象没有发生变化,始终保持其原始值

4

2 回答 2

1

如果GetSubsystem每次都返回一个新的子系统,那就是你的问题。在您绑定到视图的属性的“集合”中,您调用的是公共属性“子系统”,而不是您创建的私有字段。因此,每次您从视图中设置属性时,您都在调用 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");
}
于 2013-01-04T21:43:03.730 回答
0

您需要在视图模型中引用模型,并且视图模型会将值传递给模型。您的视图模型将实现 INotifyPropertyChanged 并将成为您视图的数据上下文。在您的视图模型中,编写您的绑定属性,如下所示:

private string yourProperty;
public string YourProperty
{
get { return yourProperty; }
set
{
if (value == yourProperty)
    return;
yourProperty= value;
YOUR_MODEL_REFERENCE.YourProperty= yourProperty;
this.RaisePropertyChanged(() => this.YourProperty);
}
}
于 2013-01-04T18:06:06.013 回答