2017-12-01 22 views
0

だから列挙型があるとして、PropertyChangedWPF双方向バインディングと

enum SampleEnum 
    { 
     Item1, 
     Item2 
    } 

その後

<ComboBox ItemsSource="{Binding SomeItemSource}"  
     SelectedItem="{Binding 
      Path=ItemX, 
      Mode=TwoWay, 
      UpdateSourceTrigger=PropertyChanged, 
      Converter={StaticResource ResourceKey=SomeConverter}}"> 

コンボボックスはそのDataContext

ViewModel : INotifyPropertyChanged, ... 
    { 
     ... 

     public SampleEnum ItemX 
     { 
      get => model.GetItemX(); 
      set 
      { 
       model.SetItemX(value); 
       RaisePropertyChanged(); 
      } 
     } 

     ... 
    } 

そしてRaisePropertyChanged([CallerMemberName] string caller = "")としてのViewModelを持つコンボボックスがありますプロパティの名前を持つPropertyChangedを呼び出します。

しかし、

私は私のコードを実行すると、私のCheckBoxを開くには、一つの項目を選択し、私は次の動作を取得する:私のコードは、セッターに入り、値が取得され、その後、私のゲッターが呼び出され、にPropertyChangedを発生させ、モデルの値を設定し、それ決してComboBoxには達しません。 ComboBoxは、私が手で選択した値を表示します。アクセサーによって返された値ではありません。

など。同じ値を返すようにget => SampleEnum.Item2を書き換えると、ComboBoxは、getterが呼び出されたことを100%確信しているにもかかわらず、自分の手でUIで選択した値を、アクセサーによって返された値ではなく、コンバーターにも適切な値が返されます。

しかしRaisePropertyChanged(nameof(ItemX))が他の場所から呼び出された場合、ComboBoxはすぐにアクセサから値を取得し、それを表示します。

つまり、ComboBoxは、setterから呼び出された場合はPropertyChangedを無視しますが、それ以外の場合は完全に正常です。コンパイラサービスに頼る代わりにプロパティの名前を直接指定するか、setterの行に複数のRasiePropertyChangedを呼び出すことはできません。

一般に、コンボボックスで選択された値とgetterによって返された値は同じですが、モデルによっては指定された値が拒否され、デフォルトの値が返されることがあります。最高の行動ではありませんが、可能です。そしてこの場合、ユーザは実際にComboBoxのどの項目が誤って選択されるでしょうか。

私はちょうどComboBoxがそれを無視するこのアクセサについて特別なのだろうかと思っています。

答えて

3

tl; dr:データ検証です。それは解決された問題です:IDataErrorInfoでビューモデルで、またはValidationRulesでビューで検証を実装することができます。いずれかの作品 WPFの代わりに。 WPFに対して作業することは、ほとんど変わらず、命題を失うことです。

無効なアイテムを無効にするComboBoxのItemContainerStyleを記述することもできます。または、ビューモデルがComboBoxアイテムコレクションを更新して、現在選択できないアイテムを除外できます。私はそのアプローチを好む:ここではなく、 "BZZZT、LOL、WRONG CHOICE!"というオプションを選ぶことができます。

あなたが選択した後にどのオプションが有効であるかを知っていれば、あらかじめほぼ確実に知ることができます。セッターから呼び出された場合


コンボボックスはにPropertyChangedを無視しますが、他の場合には、それは完全に正常に動作します。

これは正しいです。 ComboBoxはユーザーからの変更を引き続き処理しており、設定が完了してからしばらくするまでは終了しません。 ComboBoxは、現在更新中のプロパティのPropertyChangedイベントをすべて無視します。これは設計によるものです。

標準的な回避策は、BeginInvoke()をApplicationIdle優先度で呼び出し、デリゲートでPropertyChangedを発生させることです。 ComboBoxが現在の選択変更イベントで完全に終了した後、PropertyChangedを再度発生させる効果があります。しかし、これは、ビューモデルがそれ自体に関して関係するべきものではありません。

あなたが言うように、「最適な動作ではありません」が拒否するの妥当性チェックを書くことは、上記のような奇妙な回避策を書くのではなく、最初に間違った値を書き込むことが望ましいでしょう。

関連する問題