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() メソッドを使用して設定されるモデル オブジェクトです。シリアルなどのビュー モデル プロパティは、示されているようにモデルから値を取得します。プロパティのセット部分のコメントアウト行に示されているようにモデル プロパティを設定しようとしましたが、サブシステム オブジェクトに変更はなく、常に元の値を保持します

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 に答える