2017-05-02 9 views
-1

私は、MVVMと非常によく似たアーキテクチャパターンでWinFormsプログラムを作成しています。主な違いは、私がモデルとして使用しているクラスであり、ユーザーコントロールとしても機能することです。私はこれが最も素晴らしいセットアップではないかもしれないことを知っていますが、それは私が作業しなければならないものです。INotifyPropertyChangedはビューモデルを通過しません

問題は、モデル内のプロパティが変更されたとき、変更がビューに反映されていないこと、である...

私は私が正しくINotifyPropertyChangedを実装していないことを疑うています、しかし、私は間違って何かを実際に見ることはできません。私は君たちができます...

モデル

public partial class ModelAndUserControl : UserControl, INotifyPropertyChanged 
{ 
    private decimal _price; 

    public ModelAndUserControl() 
    { 
     InitializeComponent(); 
    } 

    // Implement INotifyPropertyChanged   
    public event PropertyChangedEventHandler PropertyChanged; 
    public void InvokePropertyChanged(PropertyChangedEventArgs e) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, e); 
     } 
    } 

    // Changes in this property, should be reflected in the view 
    public decimal Price 
    { 
     get { return _price; } 
     set 
     { 
      _price = value; 
      InvokePropertyChanged(new PropertyChangedEventArgs("Price"); 
     } 
    } 
} 

ビューモデル

public class MyViewModel 
{ 
    private readonly MyView view; 
    private ModelAndUserControl model; 

    public MyViewModel(MyView view, ModelAndUserControl model) 
    { 
     this.view = view; 
     this.model = model; 
    } 

    // Debugging reveals that the value of the formatted 
    // string, changes correctly when the model property changes. 
    // But the change isn't reflected in the view. 
    public string FormattedPrice 
    { 
     get { return string.format("{0:n0} EUR", model.Price); } 
    } 
} 

あなたがRAに必要なビュー

public partial class MyView : UserControl 
{ 
    private MyViewModel viewModel; 

    public MyView() 
    { 
     InitializeComponent(ModelAndUserConrol model); 

     // Create an instance of the view model 
     viewModel = new MyViewModel(this, model); 

     // Create the data binding to the price 
     txtPrice.DataBindings.Add("Text", viewModel, nameof(viewModel.FormattedPrice)); 
    } 
} 
+0

「価格」は変更されましたが、「フォーマット済み価格」は変更されていません。 – Mats391

+0

実際に両方が変更されました。しかし、基本プロパティ(この場合は 'Price')が変更された場合、すべての「派生」プロパティは基本通知の対象になると私は理解していましたか? – Noceo

+0

いいえ、あなたのデータバインディングは、 'FormattedPrice'の変更だけをリッスンします。 ViewModelを購読し、 'FormattedPrice'を呼び出すか' FormattedPrice'をスクラッチし、 'Price'を購読してビュー内でフォーマットすることによって、' PropertyChangedEvent'をバブルアップする必要があります。 – Mats391

答えて

1

願っていますバインドするビューモデルでise PropertyChangedを使用するか、またはバインド時に更新時期がわかりません。モデルが変更されたときにFormattedPriceプロパティのPropertyChangedを上げるには、このようなことができます。

public class MyViewModel : INotifyPropertyChanged 
{ 
    private readonly MyView view; 
    private ModelAndUserControl model; 

    public MyViewModel(MyView view, ModelAndUserControl model) 
    { 
     this.view = view; 
     this.model = model; 
     this.model.PropertyChanged += Model_PropertyChanged; 
    } 

    // Debugging reveals that the value of the formatted 
    // string, changes correctly when the model property changes. 
    // But the change isn't reflected in the view. 
    public string FormattedPrice 
    { 
     get { return string.format("{0:n0} EUR", model.Price); } 
    } 

    private void Model_PropertyChanged(object sender, PropertyChangedEventArgs e) 
    { 
     switch(e.PropertyName){ 
      case "Price": 
       InvokePropertyChanged("FormattedPrice"); 
       break; 
      default: 
       break; 
     } 
    } 

    // Implement INotifyPropertyChanged   
    public event PropertyChangedEventHandler PropertyChanged; 
    public void InvokePropertyChanged(PropertyChangedEventArgs e) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, e); 
     } 
    } 
}