2014-06-16 2 views
3

뷰 모델 내의 형제 속성을 기반으로하는 값을 반환하는 읽기 전용 속성이 있습니다. XAML에 바인딩하려면 형제 속성에 추가 RaisePropertyChanged 이벤트를 추가해야합니다. 이것은 조금 비 효과적이라고 느낍니다.종속 속성을 발생시키는 MVVM 패턴 RaisePropertyChanged 이벤트

단순화 된 예 :

public bool IsPurchased 
{ 
    get 
    { 
     return _IsPurchased; 
    } 
    set 
    { 
     if (_IsPurchased == value) return; 
     _IsPurchased = value; 
     RaisePropertyChanged("IsPurchased"); 
     RaisePropertyChanged("IsAvailableToUse"); 
    } 
} 
private bool _IsPurchased = false; 

public bool IsDownloaded 
{ 
    get 
    { 
     return _IsDownloaded; 
    } 
    set 
    { 
     if (_IsDownloaded == value) return; 
     _IsDownloaded = value; 
     RaisePropertyChanged("IsDownloaded"); 
     RaisePropertyChanged("IsAvailableToUse"); 
    } 
} 
private bool _IsDownloaded = false; 

public bool IsAvailableToUse 
{ 
    get 
    { 
     return IsPurchased && IsDownloaded; 
    } 
} 

사람이 기여 속성 내에서 추가 RaisePropertyChanged("IsAvailableToUse") 년대 멀리 자신을 관리하는 등의 시나리오를 쉽게하는 좋은 패턴이 있습니까? 아마도 이러한 종류의 매핑을 뷰 모델 내의 중앙 집중식 위치에 추가 할 수 있습니다.

답변

1

내가 아는 한 그 패턴은 MVVM에서 상당히 일반적입니다. 모든 속성을 함께 그룹화하려는 경우 RaisePropertyChanged 구현을 재정의하여 그룹화 된 사례를 다음과 같이 처리 할 수 ​​있습니다. 관련이없는 노트에

protected override void RaisePropertyChanged(string propertyName = null) 
    { 
     PropertyChangedEventHandler handler = this.PropertyChangedHandler; 
     switch (propertyName) 
     { 
      case "IsDownloaded": 
      case "IsAvailableToUse": 
      case "IsPurchased": 
       if (handler != null) handler(this, new PropertyChangedEventArgs("IsDownloaded")); 
       if (handler != null) handler(this, new PropertyChangedEventArgs("IsAvailableToUse")); 
       if (handler != null) handler(this, new PropertyChangedEventArgs("IsPurchased")); 

       break; 
      default: 
       if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); 
       break; 
     } 
    } 

, 나는 당신의 특성 중 하나가 "IsAvailableToUse"라는주의와 그 속성이 바인딩 명령에 대한 스위치 할 수있다처럼 보인다. 이 부울 값을 기반으로 버튼을 활성화/비활성화하는 경우 ICommand 및 CanExecute를 선언하는 것이 좋습니다. 버튼이 프레임 워크에 의해 내장 된이 유용하고 우아한 기능을 갖기 때문에 더 우아해질 수 있습니다.

+0

대단히 감사합니다. (그것은 단지 여가 시간을 허비하는 애완 동물 프로젝트를위한 것입니다.) 버튼과 관련하여 - 실제로 "구입", "다운로드", "다운로드 취소"및 "삭제"와 같은 4 개의 경우이 속성을 사용합니다. 관련 버튼을 제외한 모든 버튼을 숨기면 ICommand와 CanExecute가이 경우에 관련이 있는지 확실하지 않습니다. 스크린 샷 [http://cdn.marketplaceimages.windowsphone.com/v8/images/99281133-34ef-41c2-ac7c-33ba637c071a]. 하지만 다른 곳에서 부울 값을 사용하여 버튼을 사용 중지/사용하도록 설정 했으므로이 제안을 조사 할 것입니다. 고맙습니다. – Gavin

+0

흠 ... 나를 위해 아주 효과적이지 않습니다. 나는 MVVM Light를 사용하고 있기 때문에 그것이있을 것 같아요. MVVM Light의 "RaisePropertyChanged"와 동일한 패턴을 따릅니다. "PropertyChangedEventHandler handler = PropertyChanged"줄에서 다음과 같은 오류가 발생합니다. "이벤트 'GalaSoft.MvvmLight.ObservableObject.PropertyChanged'는 + = 또는 - =의 왼쪽에만 나타납니다. 내가 왜 핸들러를 잡을 수 없는지 아는 어떤 아이디어? – Gavin

+0

mvvm light를 다운로드하고 작동 할 답변 코드를 업데이트했습니다. –

1

이 부분은 https://github.com/steinborge/ProxyTypeHelper입니다. MVVM/WPF를 수행하고 자동으로 propertychangedevents를 연결합니다. 따라서 귀하의 예는 다음과 같습니다.

public bool IsDownloaded {get;set;} 
    public bool IsPurchased { get; set; } 

    [LinkToProperty("IsDownloaded")] 
    [LinkToProperty("IsPurchased")] 
    public bool IsAvailableToUse 
    { 
     get 
     { 
      return IsPurchased && IsDownloaded; 
     } 
    } 

    [LinkToCommand("PurchaseCommand")] 
    private void btnPurchase() 
    { 
    } 

    [LinkToCommand("DownloadCommand")] 
    private void btnDownload() 
    { 
    } 
+0

솔루션을 좋아하기 때문에 이것을 투표했습니다. 그러나 다른 대답은 MVVM Light와 호환됩니다. – Gavin

+0

나는이 해결책을 너무 좋아한다. –