2016-09-21 11 views
0

で更新されていません。のListBoxのバインドは、私は次のモデルを持っているコレクション

public class MyModel 
{ 
    public ObservableCollection<MyObject> MyList {get; set;} 
} 

public class MyObject 
{ 
    MyObservableDictionary MyDictionary {get; set;} 
} 

public class MyObservableDictionary : ObservableCollection<EnymValue> 
{ 
} 

public class EnymValue : INotifyPropertyChanged 
{ 
    private MyEnum key; 
    private string value; 

    public MyEnum Key 
    { 
     get 
     { 
      return this.key; 
     } 
     set 
     { 
      this.key = value; 
      NotifyPropertyChanged("Key"); 
     } 
    } 
    public string Value 
    { 
     get 
     { 
      return this.value; 
     } 
     set 
     { 
      this.value = value; 
      NotifyPropertyChanged("Value"); 
     } 
    } 

    public LanguageValue(MyEnum key, string value) 
    { 
     this.Key = key; 
     this.Value = value; 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    public void NotifyPropertyChanged([System.Runtime.CompilerServices.CallerMemberName]string propertyName = "") 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

public enum MyEnum 
{ 
} 

とビュー上で、私はリストボックスを持っている:

<ListBox x:Name="MyList" SelectionMode="Single" ItemsSource="{Binding Path=MyList, Mode=OneWay}"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <TextBlock Text="{Binding Path=MyDictionary, Mode=OneWay, Converter={StaticResource myEnumToTextConverter}}" /> 
     </DataTemplate> 
     </ListBox.ItemTemplate> 
</ListBox> 

(myEnumToTextConverterコンバータがちょうどコレクションから最初の要素を選択して、値が返されるか、またはコレクションがnullまたは空の場合に指定された定数が返されます)

私のモデルのリストボックスを表示するには、whe n EnymValueの値が変更されます。 これを何とか実装できますか?

現在、Valueが変更された場合、ビューは更新されません。 EnymValueINotifyPropertyChangedから継承しようとしましたが、これは役に立ちませんでした。プロパティが更新されたときに(EnymValue.NotifyPropertyChanged)のように見えます。

+1

あなたのやり方ではありません。コレクションを 'String'プロパティに束縛しているので、' Binding'は 'INotifyCollectionChanged'を購読しません。コレクションを変更すると、誰もそれについて聞くことはなく、バインディングはターゲットを更新しません。 –

答えて

2

ObservableCollectionは、コレクション自体が変更されたとき(エレメンツが追加または削除されたとき)の変更についてUIに通知することができます。しかし、ObservableCollectionは、アイテムの1つを変更するときに起こっている変更を認識していません。この問題を解決するには、CollectionChangeの観測可能な収集イベントを購読し、新しいアイテムが追加されると、新しいアイテムのPropertyChangedを購読します。 PropertyChangedイベントが発生すると、あなたのリストに通知が表示されますOnPropertyChanged(()=>MyItems);このソリューションの実装には注意が必要です。メモリリークを回避するには、イベントからの退会を忘れないようにしてください。

this answerでご覧になれます。

+0

@EdPlunkett私はちょうど提案されたソリューションをテストしたし、期待どおりに動作します。 OnPropertyChanged( "MyItems")はあなたが言及したように無視されません。必要ならば、私はそれを証明するコードを提供することができます。なぜそれを無視すべきだと思いますか? – 3615

+0

私はそれを試みたと確信していたし、それは働いていなかった。私は前に間違っていた。 –

+0

ちょうどそれをテストし、あなたが正しい、それはあなたが言うように動作します。私の注意をそれに呼んでくれてありがとう。 –

0

MyDictionaryは強制的にリフレッシュする必要があります。最も簡単な方法は、以下のようにMyObjectにでINPCをその古い値を再割り当て、実行することである。

public class MyObject: INotifyPropertyChanged 
    { 
     MyObservableDictionary _myDictionary; 
     public MyObservableDictionary MyDictionary { 
      get 
      { 
       return _myDictionary; 
      } 
      set 
      { 
       _myDictionary = value; 
       OnPropertyChanged("MyDictionary"); 
      } 
     } 

     public MyObject() 
     { 
      MyDictionary = new MyObservableDictionary(); 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 
     public void OnPropertyChanged(string prop) 
     { 
      if (PropertyChanged != null) 
       PropertyChanged(this, new PropertyChangedEventArgs(prop)); 
     } 
    } 

サンプルコードを変更する値:

private void Button_Click(object sender, RoutedEventArgs e) 
{ 
    // vm is ViewModel instance, vm is DataContext set for Window 

    var old = vm.MyList[0].MyDictionary; 
    vm.MyList[0].MyDictionary[0].Value = "aaaa"; 
    vm.MyList[0].MyDictionary = old; 
} 

私はこれをテストし、それが "として変更された値を表示しますaaaa "

関連する問題