2014-02-24 5 views
1

작동하지 않을 것이라고 기대했지만 시도하고 싶었습니다. 사용자가 응용 프로그램 (특정 컨트롤 내부)에서 아무 것도 선택했는지 알려주는 bool이 있습니다. 자동 업데이트되는 속성 바인딩하기

나는 그 부울 뭔가 바인딩 싶어 : 나는 그것을 좋아하는 것처럼이 작동하지 않습니다

 private bool _isAnythingSelected; 
    public bool IsAnythingSelected 
    { 
     get 
     { 
      _isAnythingSelected = (MyModel.Series.Where(p => p.IsSelected && p.GetType() == typeof(LineSeries)).Count() > 0); 
      return _isAnythingSelected; 
     } 
     set 
     { 
      _isAnythingSelected = value; 
      RaisePropertyChanged("IsAnythingSelected"); 
     } 
    } 

를, 그리고 왜 그런지 이해. 내 질문은, 어떻게하면 사용자가 물건을 선택할 수있는 모든 방법으로 가지 않고이 선택 물건을 구현해야합니까? 고맙습니다.

+0

'MyModel'구현을 변경할 수 있습니까? – Dennis

답변

1

제대로 IsAnythingSelected를 업데이트하려면 알림 두 종류의 처리 할 수 ​​있습니다

  • 통지에 대한 MyModel.Series 컬렉션 변경을;
  • 알림 MyModel.Series 컬렉션 상품 속성이 변경되었습니다.

첫 번째는 달성 할 수 INotifyCollectionChanged를 구현 ObservableCollection<T>와 (또는 다른 모음 "상자 밖으로".
두 번째는 사용자 지정 솔루션 (적어도 내가 어떤 존재를 모르는이 필요 . 한)

"상자 밖으로"당신은 처리 항목의 속성이 방법 ObservableCollection<T> 변경 결합 할 수 있습니다 :

class MyObservableCollection<T> : ObservableCollection<T> 
    where T : INotifyPropertyChanged 
{ 
    private void Initialize() 
    { 
     // initial PropertyChanged subscription 
     foreach (var item in Items) 
     { 
      SubscribeItemPropertyChanged(item); 
     } 
    } 

    private void SubscribeItemPropertyChanged(object item) 
    { 
     ((INotifyPropertyChanged)item).PropertyChanged += HandleItemPropertyChanged; 
    } 

    private void UnSubscribeItemPropertyChanged(object item) 
    { 
     ((INotifyPropertyChanged)item).PropertyChanged -= HandleItemPropertyChanged; 
    } 

    protected virtual void HandleItemPropertyChanged(object sender, PropertyChangedEventArgs args) 
    { 
     var handler = ItemPropertyChanged; 
     if (handler != null) 
     { 
      handler(sender, args); 
     } 
    } 

    protected override void ClearItems() 
    { 
     // we should unsubscribe from INotifyPropertyChanged.PropertyChanged event for each item 
     Items.ToList().ForEach(item => Remove(item)); 
    } 

    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e) 
    { 
     base.OnCollectionChanged(e); 

     // subscribe for new items property changing; 
     // un-subscribe for old items property changing 
     switch (e.Action) 
     { 
      case NotifyCollectionChangedAction.Add: 
       SubscribeItemPropertyChanged(e.NewItems[0]); 
       break; 
      case NotifyCollectionChangedAction.Remove: 
       UnSubscribeItemPropertyChanged(e.OldItems[0]); 
       break; 
      case NotifyCollectionChangedAction.Replace: 
       SubscribeItemPropertyChanged(e.NewItems[0]); 
       UnSubscribeItemPropertyChanged(e.OldItems[0]); 
       break; 
     } 
    } 

    public MyObservableCollection() 
     : base() 
    { 
    } 

    public MyObservableCollection(IEnumerable<T> collection) 
     : base(collection) 
    { 
     Initialize(); 
    } 

    public MyObservableCollection(List<T> list) 
     : base(list) 
    { 
     Initialize(); 
    } 

    public EventHandler<PropertyChangedEventArgs> ItemPropertyChanged; 
} 

을 ... 그리고 MyModel.SeriesMyObservableCollection<T> 인스턴스를 만들. 다음, IsAnythingSelected가 포함 된 클래스는 다음과 같이 표시됩니다 : 당신은 심지어이 경우 읽기 - 쓰기 속성으로 IsAnythingSelected 필요하지 않습니다

// somewhere in code, where `MyModel` being initialized: 
MyModel.Series.CollectionChanged += (sender, args) => RaisePropertyChanged("IsAnythingSelected"); 
MyModel.Series.ItemPropertyChanged += (sender, args) => RaisePropertyChanged("IsAnythingSelected"); 

    public bool IsAnythingSelected 
    { 
     get 
     { 
      return MyModel.Series.Any(p => p.IsSelected && p.GetType() == typeof(LineSeries)); 
     } 
    } 

. 그것이 변경되었다는 것을 알리면 바인딩 엔진은 그 가치를 다시 읽습니다.