WPF默认按钮命令不触发文本框中的绑定

时间:2011-07-15 22:04:49

标签: wpf mvvm binding

我有一个搜索屏幕,其中包含一些文本框和一个搜索按钮作为默认设置。如果我输入文本框并点击按钮,一切都很棒。但是,如果我在文本框中按Enter键,则会触发按钮命令,但是我所处理的任何文本框上的绑定都不会触发,因此我的条件不会使其进入视图模型以进行过滤。

我知道一个解决方法是将文本框上的绑定设置为PropertyChanged,但这似乎有些过分。我可能在viewmodel中有逻辑做事情,我不希望它在每次击键时触发。

我真正想要的是按钮本身触发焦点变化或以某种方式触发绑定的方式。或者如果焦点丢失,让文本框触发绑定,或者按Enter键或从任何地方执行命令

3 个答案:

答案 0 :(得分:4)

执行此操作的一种方法是使用BindingGroup。

http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.bindinggroup.aspx

如果您的TextBox()和Button都包含在Grid中(例如),您可以像这样添加BindingGroup:

<Grid>
    <Grid.BindingGroup>
        <BindingGroup Name="bindingGroup1"/>
    </Grid.BindingGroup>

然后你可以在你的按钮上添加一个Click事件处理程序,并在BindingGroup上调用CommitEdit()(Button和TextBox从Grid继承):

private void button1_Click(object sender, RoutedEventArgs e)
{
    (sender as FrameworkElement).BindingGroup.CommitEdit();
}

Button.Click事件在CommandBinding之前触发,因此在执行视图模型命令之前,应该更新该BindingGroup中的任何数据绑定TextBox或任何其他数据绑定控件。

答案 1 :(得分:1)

我有你刚刚提到的确切场景。我使用的技巧是附加行为,它位于控件上并侦听PreviewKeyDown事件。它检查输入是否被按下。如果是这样,它会强制控件失去焦点,从而导致绑定在命令执行之前触发。

答案 2 :(得分:1)

更简单的方法(而不是使用绑定组)是使用默认按钮的click事件将焦点设置为自身。因为这在命令执行之前发生,这意味着ViewModel会及时更新。

private void button1_Click(object sender, RoutedEventArgs e)
{
    (sender as Button).Focus()
}

如果你真的讨厌代码,你总是可以写一个附属物......