2012-06-08 3 views
1

결합을 통해 수집 누락 된 항목이 추가 :처음 감안할 때

class StringRecord : INotifyPropertyChanged 
{ 
    public string Key { get; set; } // real INPC implementation is omitted 
    public string Value { get; set; } // real INPC implementation is omitted 
    ... 
} 

class Container 
{ 
    public ObservableKeyedCollection<string, StringRecord> Params { get; set; } 
    ... 
{ 

ObservableKeyedCollectionthe one found here입니다.

이 텍스트 상자는 (DataContext를 상속한다) 수집 항목 중 하나에 바인딩 :

<TextBox Text="{Binding Params[APN_HOST].Value}"/> 

내가 수동으로 컬렉션에 "APN_HOST"항목을 추가 할 때, 바인딩 작품은 예상대로. 내가 갇혀있어 이제

: 나는 즉 그런 식으로 빈 콜렉션을 편집 할 수 있도록하려면,

지정된 키 컬렉션에는 항목이없는 경우 및 사용자 유형의 텍스트 텍스트 상자에 해당 키가있는 컬렉션에 새 항목이 추가됩니다.

나는 컬렉션의 의미를 "발견되지 않는 경우는 기본"어떤 종류의를 구현하기 위해 노력하지만, 하나의 값 :

를 공유하는 모든 텍스트 상자가 StringRecord의 동일한 기본 인스턴스에 바인딩되는 결과

내가 여기에서 정말로 명백한 무엇인가를 멀리 바라보고있는 것처럼 느낀다.

+0

[BindingBase.FallbackValue] (http://msdn.microsoft.com/en-us/library/system.windows.data.bindingbase.fallbackvalue) 또는 [BindingBase.TargetNullValue] (http : // msdn Microsoft.com/ko-kr/library/system.windows.data.bindingbase.targetnullvalue)? – LPL

+0

@LPL 그래, 텍스트 상자에 예상대로 올바르게 표시되지만 편집하면 새 항목이 여전히 컬렉션에 추가되지 않습니다. – vines

답변

0

음, 정말 힘든 일이었습니다! 내가 무슨 짓을했는지

은 다음과 같습니다 ObservableKeyedCollection를 확장

1) 인덱서는 바인딩 엔진이 제대로 해결, new로 선언되는 것을에도 불구하고

public class ObservableKeyedCollection<TKey, TItem> : KeyedCollection<TKey, TItem>, INotifyCollectionChanged 
{ 
    ... 
    Func<TKey,TItem> m_newItemDelegate; 

    public ObservableKeyedCollection(Func<TItem, TKey> getKeyForItemDelegate, Func<TKey, TItem> newItemDelegate = null) 
     : base() 
    { 
     ... 
     m_newItemDelegate = newItemDelegate; 
    } 

    public new TItem this[TKey key] 
    { 
     get 
     { 
      if (m_newItemDelegate != null && !Contains(key)) 
      { 
       TItem i = m_newItemDelegate(key); 
       var i_as_inpc = i as INotifyPropertyChanged; 
       if (i_as_inpc != null) 
        i_as_inpc.PropertyChanged += new PropertyChangedEventHandler(AddItemOnChangeHandler); 
       else 
        Add(i); 
       return i; 
      } 
      return base[key]; 
     } 
     set 
     { 
      if (Contains(key)) Remove(key); 
      Add(value); 
     } 
    } 

    private void AddItemOnChangeHandler(object sender, PropertyChangedEventArgs e) 
    { 
     (sender as INotifyPropertyChanged).PropertyChanged -= AddItemOnChangeHandler; 
     Add((TItem)sender); 
    } 
  • 와 함께.
  • new-item-delegate가 제공되면 누락 된 키에 대한 기본 항목 인스턴스를 얻기 위해 new-item-delegate를 사용합니다. 이 새 항목은 컬렉션에 즉시 추가되지 않습니다. 사용자가 실제로 값을 편집 한 후에 값을 추가해야한다는 요구 사항을 위반할 수 있기 때문입니다. 대신
  • 항목에 INotifyPropertyChanged을 구현하는 경우 해당 PropertyChanged 이벤트에 연결하고 처리기에서 컬렉션에 항목을 추가하고 즉시 PropertyChanged에서 수신 거부하십시오.

이것만으로도 충분하지만, 몇 가지 이상한 이유로 중첩 된 속성 알림이 실행되지 않습니다!

<TextBox DataContext="{Binding Params[APN_HOST]}" Text="{Binding Value}" /> 

를 지금은 발사 상기 트리거기구, 다음과 같이

2) 결합 재기록!

EDIT. 어떤 토론이 here으로 진행된 후, 두 번째 수정은 기본값 동작으로 인해 솔루션의 피할 수없는 부분이었습니다. 어떤 인스턴스가 변경되었는지를 판별 할 수있는 다른 가능성은 없습니다.