2013-06-13 2 views
1

TextBox을 내 ViewModel 속성에 바인딩합니다. 사용자가 ApplicationBar Button을 클릭하면 명령이 호출됩니다 (NuGet에서 찾을 수있는 BindableApplicationBar를 사용하고 있습니다). 문제는 사용자가 TextBox을 입력하고 응용 프로그램 버튼을 즉시 클릭하면 TextBox의 설정자가 호출되지 않는다는 것입니다. 이는 ButtonCommand가 이전 텍스트를 사용하고 있음을 의미합니다.ApplicationBar 명령 전에 LostFocus

많은 솔루션을 보았지만 제 상황에서는 사용할 수 없습니다. 유일한 해결책은 ApplicationBar를 없애고 대신 키보드 뒤에있는 버튼을 사용하는 것입니다.이 버튼은 사용자가 TextBox를 클릭 할 때 팝업됩니다. 저는 Windows Phone을 사용하므로 KeyBoard가 있습니다. ..). 그래서 사용자는 버튼 -> lostfocus를 사용하기 위해 다른 곳을 클릭해야합니다.

일부 솔루션 :

WPF Databind Before Saving

Binding with UpdateSourceTrigger==LostFocus do not fire for Menu or Toolbar interaction

내가 UpdateSourceTrigger =하여 PropertyChanged를 사용하지 못할 내가 MVVM을 사용하고, 그래서 나 또한 정말하지 않는 코드 숨김을 사용하고 싶습니다. CodeBehind 없이는 다른 방법이 없다면 괜찮습니다.

답변

0

이전에 사용한 적이있는 한 가지 해결책은 포커스가 손실되었을 때가 아니라 텍스트 상자의 내용이 변경 될 때마다 바인딩을 업데이트하는 것입니다.

간단하고 재사용 가능한 방법은 동작입니다. 이 같은

뭔가 :

public class RebindOnTextChanged : Behavior<TextBox> 
{ 
    protected override void OnAttached() 
    { 
     base.OnAttached(); 
     this.AssociatedObject.TextChanged += this.TextChanged; 
    } 

    protected override void OnDetaching() 
    { 
     base.OnDetaching(); 
     this.AssociatedObject.TextChanged -= this.TextChanged; 
    } 

    private void TextChanged(object sender, TextChangedEventArgs e) 
    { 
     var bindingExpression = this.AssociatedObject.GetBindingExpression(TextBox.TextProperty); 
     if (bindingExpression != null) 
     { 
      bindingExpression.UpdateSource(); 
     } 
    } 
}  

과 같이 사용 :

<TextBox Text="{Binding SomeProperty}"> 
    <i:Interaction.Behaviors> 
     <behaviours:RebindOnTextChanged /> 
    </i:Interaction.Behaviors> 
</TextBox> 
0

여기에서 발생하는 문제 (또는 프레임 워크의 버그?)는 AppBar이 실제 Silverlight 컨트롤이 아니므로 포커스를 훔치는 관점에서 다르게 처리되고 있습니다. 나는 이것이 당신의 디자인에 맞는 방법을 잘 모르겠지만, 내 애플 리케이션 중 하나에서 나는 다음과 같은 패턴을 사용 :

void appBarButton_Click(object sender, EventArgs e) 
    { 
     // removal of focus from the TextBox to the Page will force the bind. 
     this.Focus(); 

     // wait till the next UI thread tick so that the binding gets updated 
     Dispatcher.BeginInvoke(() => 
     { 
      // at this point the binding is updated 
      MessageBox.Show(RandomText); 
     }); 
    } 

이 총의 종류를하지만 서로 다른 경로의 수를 래핑하는 도우미 함수를 사용하는 여분의 파견이나 버튼 조작 후 초점을 훔치려는 통제에 대해 알 필요가 없도록 해당 작업을 수행하고있었습니다.