如何失去对按钮的关注?

时间:2012-08-21 12:56:23

标签: wpf mvvm lost-focus

简化为: 在我看来,我有一个包含按钮和某种TextBox的xaml页面。该按钮绑定到ViewModel中的DelegateCommand,editbox绑定到ViewModel中的某个属性。

View:
<Button Command="{Binding MyCommand}"/>
<TextBox Text="{Binding MyString}"/>

ViewModel:
public DelegateCommand MyCommand { get; set; }
public String MyString { get; set; }

现在,当用户在框中输入内容并单击按钮时,该按钮不会收到焦点更改事件。因此它不会将其内容更新为该属性。因此,单击按钮时,属性MyString不会反映TextBox的内容。因此无论MyCommand处理什么,它都处理旧数据而不是当前输入。

现在,如果这真的只是一个TextBox,我会将UpdateSourceTrigger = PropertyChanged添加到绑定中,我会很好。 但在这种情况下,编辑控件有点复杂,需要对内容进行一些验证。 所以当用鼠标按下按钮时,我需要某种“失焦”信号。

我的问题是:在MVVM中,按钮后面的代码没有对视图的任何访问权限,因此无法使其失去焦点。

在xaml中是否有任何方法(例如在视图中)使按钮在鼠标单击时获得键盘焦点?这将是我的自定义控件获取“失去焦点”消息的最简单方法。

2 个答案:

答案 0 :(得分:1)

是否仍然无法使用Button的click事件并且后面的代码会使文本框失去焦点?

private void Button_Click(object sender, RoutedEventArgs e) { 
    FocusManager.SetFocusedElement(this, null); 
} 

以下答案是否适合您?

WPF Reset Focus on Button Click

答案 1 :(得分:1)

Re:在xaml中是否有任何方法(例如在视图中)使按钮在鼠标点击时获得键盘焦点? &GT;单击按钮时确实会收到键盘焦点 - 前提是IsEnabled,Focusable和IsHitTestVisible属性都默认设置为true。要以编程方式设置键盘焦点,请调用Keybaord.Focus,如下例所示。

与流行的模因相反,命令不必在VM中处理。如果在命令执行时需要独立于VM更改视图,则可以在视图中处理该命令。实际上这是WPF的原生模式。

以下示例显示使用按钮上的Command属性处理视图中的命令。为简单起见,该示例没有VM。即使在视图中处理命令,如果有VM,视图中的代码也可以调用它。

public partial class MainWindow : Window
{
    public static readonly RoutedUICommand MyCommand = new RoutedUICommand("My Command", "MyCommand", typeof(MainWindow));
    public String MyString { get; set; }

    public MainWindow()
    {
        MyString = "some text";
        DataContext = this; // this simple example has no VM 
        InitializeComponent();
    }
    private void MyCommand_Executed(object sender, ExecutedRoutedEventArgs e)
    {
        Button1.Content = MyString;
        Keyboard.Focus(Button1);   
    }
}
<Window x:Class="fwLoseFocus.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:me="clr-namespace:fwLoseFocus">
    <Window.CommandBindings>
        <CommandBinding Command="me:MainWindow.MyCommand" Executed="MyCommand_Executed"/>
    </Window.CommandBindings>
    <StackPanel>
        <TextBox Text="{Binding MyString}"/>
        <Button x:Name="Button1" Command="me:MainWindow.MyCommand"/>
    </StackPanel>
</Window>