ApplicationBar命令之前的LostFocus

时间:2013-06-13 08:39:10

标签: c# data-binding binding windows-phone lostfocus

我正在将TextBox绑定到我的ViewModel的属性。 当用户单击ApplicationBar Button时,正在调用一个命令(我正在使用BindableApplicationBar,它可以在NuGet上找到)。问题是,当用户键入TextBox并立即单击应用程序按钮时,TextBox的setter未被调用,这意味着ButtonCommand正在使用旧文本。

我见过很多解决方案,但我不能在我的情况下使用它们。唯一的“解决方案”是摆脱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。如果没有其他方法可以在没有CodeBehind的情况下进行,那就没关系。

2 个答案:

答案 0 :(得分: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);
        });
    }

这有点粗略,但是我使用辅助函数来包装许多不同的路径,这样他们就不必知道额外的调度,或者哪个控件在点击之后会偷走焦点。按钮。

答案 1 :(得分: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>