none
用Focus()方法使textbox重新获得焦点,为什么光标不能正常闪烁? RRS feed

  • 问题

  • 想实现这样的功能:当TextBox中输入的内容不符合某种内容时,在LostKeyboardFocus或LostFocus事件中重新获取焦点,比如:
            private void textBox3_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
            {
                if (textBox3.Text != "abc")
                {
                    textBox3.Focus();
                }  
            }
    这样虽然能使textBox3重获焦点,但光标是静止不动的,而不是正常闪烁,这是什么原因?怎样处理?
    2014年4月17日 2:54

答案

  • 不能用PreviewLostKeyboardFocus,因为textbox3控件有Binding,我还需要用到系统提供的validation,而这个validation是在LostKeyboardFocus事件之后发生的。

    数据绑定是在LostFocus事件里面作用的,你可以在PreviewLostKeyboardFocus事件里面手动调用产生LostFocus事件即可,代码如下:

            void textBox3_PreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
            {
                if (textBox3.Text != "abc")
                {
                    e.Handled = true;
    
                    RoutedEventArgs arg = new RoutedEventArgs(TextBox.LostFocusEvent, textBox3);
                    textBox3.RaiseEvent(arg);
                }  
            }

    或者把绑定的UpdateSourceTrigger设置为PropertyChanged,这样不需要焦点丢失也能使绑定起作用。

    如果真的要折腾这个光标的闪动问题,使用PreviewLostKeyboardFocus事件应该是最简单的方法了


    • 已编辑 lapheal 2014年4月17日 9:51
    • 已标记为答案 seewold 2014年4月18日 5:07
    2014年4月17日 9:48

全部回复

  • 应该使用PreviewLostKeyboardFocus事件,如下所示:

            void textBox3_PreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
            {
                if (textBox3.Text != "abc")
                {
                    e.Handled = true;
                }  
            }
    这样光标就能正常闪烁了,你可以试一下



    • 已编辑 lapheal 2014年4月17日 9:45
    2014年4月17日 4:19
  • 你好,

    既然文本框输入不符合规范,可以尝试先清空文本框,然后再获取焦点,如:

       private void textBox3_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
            {
                if (textBox3.Text != "abc")
                {
                     textBox3.Text ="";
                     textBox3.Focus();
                }  
            }


    Lisa Zhu [MSFT]

    2014年4月17日 8:01
    版主
  • 不能用PreviewLostKeyboardFocus,因为textbox3控件有Binding,我还需要用到系统提供的validation,而这个validation是在LostKeyboardFocus事件之后发生的。
    2014年4月17日 8:46
  • 这样不行的,当鼠标点击到其他控件时,最终textBox3根本无法获得焦点。
    2014年4月17日 9:05
  • 不能用PreviewLostKeyboardFocus,因为textbox3控件有Binding,我还需要用到系统提供的validation,而这个validation是在LostKeyboardFocus事件之后发生的。

    数据绑定是在LostFocus事件里面作用的,你可以在PreviewLostKeyboardFocus事件里面手动调用产生LostFocus事件即可,代码如下:

            void textBox3_PreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
            {
                if (textBox3.Text != "abc")
                {
                    e.Handled = true;
    
                    RoutedEventArgs arg = new RoutedEventArgs(TextBox.LostFocusEvent, textBox3);
                    textBox3.RaiseEvent(arg);
                }  
            }

    或者把绑定的UpdateSourceTrigger设置为PropertyChanged,这样不需要焦点丢失也能使绑定起作用。

    如果真的要折腾这个光标的闪动问题,使用PreviewLostKeyboardFocus事件应该是最简单的方法了


    • 已编辑 lapheal 2014年4月17日 9:51
    • 已标记为答案 seewold 2014年4月18日 5:07
    2014年4月17日 9:48
  • 不能用PreviewLostKeyboardFocus,因为textbox3控件有Binding,我还需要用到系统提供的validation,而这个validation是在LostKeyboardFocus事件之后发生的。

        尝试使用下面的代码呢, 我这边是没有问题的:

     <StackPanel>
            <TextBox Name ="mytestbox" LostKeyboardFocus="mytestbox_LostKeyboardFocus" >
                <TextBox.Text >
                    <Binding Path="Name" >
                        <Binding.ValidationRules>
                            <ExceptionValidationRule/>
                        </Binding.ValidationRules>
                    </Binding>
                </TextBox.Text>
            </TextBox>  
            <Button>Click</Button>
        </StackPanel>

     public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
    
                Class1 c1 = new Class1();
                c1.Name = "abc";
                this.DataContext = c1;
            }
    
            private void mytestbox_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
            {
                if (mytestbox.Text != "aaa")
                {
                    mytestbox.Text ="";
                    this.Focus();
                }
            }
    
            public class Class1
            {
                private string _name;
                public string Name
                {
                    get { return _name; }
                    set
                    {
                        _name = value;
                        if (value =="a")
                        {
                            throw new ApplicationException("Customer name should not be a.");
                        }
                    }
                }
            }
        }


    Lisa Zhu [MSFT]

    2014年4月17日 10:15
    版主
  • PreviewLostKeyboardFocus和手工激发LostFocus事件,很好,谢谢!

    网上搜到的另外一个方法也可以:

                this.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Render, new Action(() =>
                {
                    textBox3.Focus();
                }));

    2014年4月18日 1:28
  • 也是个办法,谢谢
    2014年4月18日 1:35