2014-11-23 5 views
0

Caliburn.Micro를 사용하고 있으며 확인 가능한 메뉴 항목을 추가하려고합니다. 이 액션의 처리기는 메뉴 항목의 상태 (체크 여부)를 알아야합니다.Checkable 메뉴 항목의 이벤트 처리기에서 IsChecked 속성을 얻는 방법

XAML (오류 복구를위한 코드를 포함하지 않음)

<MenuItem Header="Laser" x:Name="ToggleLaser" VerticalAlignment="Top" IsCheckable="True" IsChecked="{Binding LaserState}" > 

뷰 모델 :

public IEnumerable<IResult> ToggleLaser(bool isChecked) 
{ 
    yield return BusyResult.Show("Turning laser " + (isChecked ? "on" : "off"); 
    if (isChecked) 
     yield return TurnOnLaserAsync().AsResult(); 
    else 
     yield return TurnOffLaserAsync().AsResult();    
    LaserState = isChecked; 
    yield return BusyResult.Hide(); 
} 

이 작동하지 않았다 -의 IsChecked는에 allways 거짓이었다.

public IEnumerable<IResult> ToggleLaser(RoutedEventArgs eventArgs) 
{ 
    var menuItem = (MenuItem)eventArgs.OriginalSource; 
    var isChecked = menuItem.IsChecked; 
    return ToggleLaser(isChecked); 
} 

을하지만 내 뷰 모델은 내보기에 바인딩 - 좋은하지 :

나는 있는 EventArgs를 얻을 수 있습니다.

여기에 좋은 답변을 찾을 수 없으므로 메뉴 항목에 대한 꽤 일반적인 사용 사례라고 생각합니다.

 MessageBinder.SpecialValues.Add("$ischecked", context => 
     { 
      var args = context.EventArgs as RoutedEventArgs; 
      if (args == null) { 
       return null; 
      } 
      var fe = args.OriginalSource as MenuItem; 
      if (fe == null) { 
       return null; 
      } 
      return fe.IsChecked; 
     }); 

그리고 내 XAML이된다 : 내가 생각 해낸

+1

왜''과 같은 사용자 표준 바인딩을 사용하지 않으시겠습니까? 'caliburn'에서 뭔가가 바뀌 었습니까? –

+0

당신은 정확합니다 - 표준 바인딩 작업 - 제 질문은 명확하지 않았습니다 - 문제는 ToggleLaser가 시간이 걸리는 것입니다 - 질문에있는 코드를 업데이트 할 것입니다 – espenalb

답변

0

하나의 솔루션으로, 새로운 데이터 바인딩 키워드를 추가하여 caliburn 프레임 워크를 확장하는 것이다

<MenuItem Header="Laser" x:Name="ToggleLaser" VerticalAlignment="Top" IsCheckable="True" cal:Message.Attach="ToggleLaser($ischecked)"/> 

을 그리고 내 뷰 모델은

된다
public void ToggleLaser(bool turnOn) 
    { 
     if (turnOn) 
      TurnOnLaser(); 
     else 
      TurnOffLaser(); 
    } 

훨씬 좋네요. :-)

두 번째 옵션은 menuitem IsChecked 속성을 databind하는 것입니다. 이것은 무언가가 레이저를 켜지 않는 경우를 처리하는 이점이 있지만, 속성 설정자에서 복잡한 함수를 호출하는 것을 좋아하지 않습니다. 그래서 더 나은 솔루션은 IsChecked 데이터 바인딩에 있다고 생각합니다 특정 처리기를 사용합니다.

많은 의견을 환영합니다.

0

MenuItemIsChecked 속성을 포함합니다.

당신은 단순히 다음과 같은 작업을 수행 할 수

<MenuItem Header="Laser" 
      x:Name="ToggleLaser" 
      VerticalAlignment="Top" 
      IsCheckable="True" 
      IsChecked="{Binding IsLaserOn}"> 

그리고 뷰 모델을 :

public bool IsLaserOn 
{ 
    get { return this.isLaserOn; } 
    set 
    { 
     if (value == this.isLaserOn) 
      return; 

     this.isLaserOn = value; 
     this.RaisePropertyChanged("IsLaserOn"); 
     this.ToggleLaser(this.isLaserOn); 
    } 
} 

그것은 일부 MessageBinder을 만드는 것보다 더 간단하다.

+0

동의합니다 - 더 간단합니다. 그러나 ToggleLaser에 문제가 발생하여 문제가 발생할 수 있습니다. 그래서 Enumerable 명령을 사용하여 사용자에게 전달하려고합니다. 코드 샘플을 업데이트합니다. – espenalb

+0

여기에 몇 가지 옵션이 있습니다. TPL을 명시 적으로 사용할 수도 있고 바인딩을 만들 때 IsAsync 속성을 사용할 수도 있습니다. – stukselbax