1

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

我已经看到了很多解决方案,但我无法在我的情况下使用它们。唯一的“解决方案”是摆脱 ApplicationBar 并使用一个按钮,它位于键盘后面(当用户单击 TextBox 时会弹出。我使用的是 Windows Phone,所以这就是为什么有一个键盘。 ..)。所以用户必须点击其他地方才能使用按钮-> lostfocus。

一些解决方案:

保存前的 WPF 数据绑定

与 UpdateSourceTrigger==LostFocus 绑定不会触发菜单或工具栏交互

我不能使用 UpdateSourceTrigger=PropertyChanged 并且我正在使用 MVVM,所以我也不想使用 CodeBehind。如果没有 CodeBehind 就没有其他方法可以做到这一点,那么没关系。

4

2 回答 2

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);
        });
    }

这有点恶心,但我使用了一个辅助函数来包装许多不同的路径,这样他们就不必知道额外的调度,或者在点击按钮后哪个控件会窃取焦点。

于 2013-06-13T16:23:50.450 回答
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>
于 2013-06-13T16:42:28.643 回答