2017-12-01 2 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 = "")로 뷰 모델이있는 콤보 상자가 속성 이름이있는 PropertyChanged을 호출합니다.

그러나. 내 코드를 실행하면

, 내 CheckBox 열 한 항목을 선택, 내가 행동 다음 얻을 : 내 코드, 세터를 입력 모델의 값을 설정하여 PropertyChanged이 제기 한 다음 내 게터가 호출, 값이 검색되고, 하지만 결코ComboBox에 도달하지 않습니다. ComboBox은 접근 자에 의해 반환 된 값이 아니라 내가 직접 선택한 값을 표시합니다.

예. 항상 동일한 값을 반환하기 위해 get => SampleEnum.Item2을 다시 쓰면 ComboBox은 getter가 호출 된 것임을 확신하지만 getter가 반환 된 값이 아니라도 접근자가 반환 한 값이 아니라 UI에서 내 손으로 선택한 값을 계속 표시합니다. to Converter 및 Convrter도 적절한 값을 반환합니다.

그러나RaisePropertyChanged(nameof(ItemX)) 경우가 다른 곳에서 호출, ComboBox 즉시 접근에서 값을 검색하고 표시합니다.

간단히 말해서 ComboBox은 setter에서 호출하면 PropertyChanged을 무시하지만 다른 경우에는 완벽하게 정상적으로 작동합니다. 컴파일러 서비스에 의존하는 대신 속성의 이름을 직접 지정하거나 setter의 행에서 여러 RasiePropertyChanged를 호출하면 작동하지 않습니다.

일반적으로 콤보 상자에서 선택한 값과 getter에서 반환 한 값이 같지만 모델에서 제공된 값을 거부하고 대신 기본값을 반환 할 수 있다고 예상해야합니다. 최고의 행동은 아니지만 가능합니다. 그리고이 경우 실제로 사용자가 ComboBox의 어떤 항목을 잘못 알게됩니다.

ComboBox가 무시하는이 접근 자에 대해 특별한 점이 있습니다.

답변

3

tl; dr : 데이터 유효성 검사가 수행하려고합니다. 그게 해결 된 문제입니다 : IDataErrorInfo으로 뷰 모델에서 유효성 검증을 구현하거나 ValidationRules으로 뷰에서 유효성 검증을 구현할 수 있습니다. WPF 대신에 WPF 중 하나가 작동합니다. WPF에 대한 작업은 거의 변함없이 명제를 잃고 있습니다.

잘못된 항목을 사용할 수 없게하는 ComboBox의 ItemContainerStyle을 작성하거나 viewmodel이 현재 선택할 수없는 항목을 제외하도록 ComboBox 항목 컬렉션을 업데이트 할 수 있습니다. 나는 그 접근 방식을 선호합니다 : "여기보다는 당신이 BZZZT, LOL, WRONG CHOICE 중 하나를 선택할 수 있습니다!"라는 옵션을 그들에게만 선물하는 것이 더 좋을 것 같습니다. 을 선택하십시오.

그리고 선택을 한 후에 어떤 옵션이 유효한지 알 수 있다면 사전에 거의 확실하게 알 수 있습니다.세터에서 호출하는 경우


콤보 상자하여 PropertyChanged를 무시하지만 다른 케이스에 완벽하게 잘 작동합니다.

맞습니다. ComboBox는 사용자로부터받은 변경 사항을 처리하고 있으며 설정 기가 완료 될 때까지 완료하지 않습니다. ComboBox는 현재 업데이트중인 속성의 PropertyChanged 이벤트를 무시합니다. 이는 의도적으로 설계된 동작입니다.

표준 해결 방법은 BeginInvoke()를 ApplicationIdle 우선 순위로 호출하고 대리인에서 PropertyChanged를 발생시키는 것입니다. ComboBox가 현재 선택 변경 이벤트로 완전히 끝난 후에 PropertyChanged를 다시 발생시키는 효과가 있습니다. 하지만 그것은 뷰 모델이 그 자체로 관련되어야하는 것은 아닙니다.

"최선의 행동이 아니므로". 이 위와 같은 이상한 해결 방법을 쓰기보다는 잘못된 값을 첫 번째로 거부하는 유효성 검사를 작성하는 것이 좋습니다.

관련 문제