WPF的TextBox的焦点获取与失去焦点的死循环解决方案

在WPF中实现一个弹出层自动获取焦点,弹出层实现是通过其UserControl的依赖属性Visibility的绑定实现的,让UserControl上的TextBox获取焦点,初始实现代码如下:

        public Visibility IsVisibile
        {
            get { return (Visibility)GetValue(IsVisibileProperty); }
            set { SetValue(IsVisibileProperty, value); }
        }
        public static readonly DependencyProperty IsVisibileProperty =
            DependencyProperty.Register("IsVisibile", typeof(Visibility), typeof(WordsKeyboard), new PropertyMetadata(Visibility.Collapsed,new PropertyChangedCallback((d,e)=>
                {
                    if((Visibility)e.NewValue==Visibility.Visibile)
                     (d as MainUserControl).textBox.Focus();

                })));

但是第一次弹出该层的时候焦点未在textBox上,除了第一次弹出未获取到焦点后面的弹出都获取到了,为了解决第一次弹出层的TextBox未获取到焦点采用了定时器延时的方法,解决方案如下:

/// <summary>
        /// 定义个定时器
        /// </summary>
        DispatcherTimer timer = new DispatcherTimer();
        /// <summary>
        /// 构造方法
        /// </summary>
        public MainUserContrl()
        {
            InitializeComponent();
            timer.Interval = new TimeSpan(500);
            timer.Tick += timer_Tick;
        }

        /// <summary>
        /// 定时器间隔执行方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void timer_Tick(object sender, EventArgs e)
        {
            this.MainText.Focus();
            timer.Stop();
        }
 /// <summary>
        /// 控制改用户控件显示隐藏的依赖属性
        /// </summary>
        public Visibility IsVisibile
        {
            get { return (Visibility)GetValue(IsVisibileProperty); }
            set { SetValue(IsVisibileProperty, value); }
        }
        public static readonly DependencyProperty IsVisibileProperty =
            DependencyProperty.Register("IsVisibile", typeof(Visibility), typeof(WordsKeyboard), new PropertyMetadata(Visibility.Collapsed,new PropertyChangedCallback((d,e)=>
                {
                    if((Visibility)e.NewValue==Visibility.Collapsed)
                    (d as WordsKeyboard).KillKeyboard();
                    else
                    {
                        (d as MainUserControl).timer.Start();//开启定时器,让textBox获取到焦点
                    }
                })));

通过延时的方法就可以解决掉弹出层第一次无法获取焦点的问题了!而后面让textbox在能使用的情况下不能失去焦点(除非点击弹出层的关闭按钮,让弹出层消失),初始实现代码如下:

  /// <summary>
        /// textBox失去焦点事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void textBox_LostFocus(object sender,RoutedEventArgs e)
        {
            if(textBox.IsEnabled&&!btnCancle.IsFocused)
            textBox.Focus();
        }

上述实现,会出现死循环,假如不出现死循环btnCancle.IsFocused的值一直是false,因为取消按钮一直没有获取到焦点!而解决方案实现如下:

 DispatcherTimer timerLoseFocuse = new DispatcherTimer();
 timerLoseFocuse.Interval = new TimeSpan(0,0,0,0,100);
            timerLoseFocuse.Tick+=(s,e)=>
                {
                    if(CardNumArea.IsEnabled&&!BtnCancel.IsFocused)
                    {
                        this.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Render,new Action(()=>
                        {
                            t.extBox.Focus();
                        }));//改方法能解决掉LoseFocuse出现死循环的问题
                    }
                    timerLoseFocuse.Stop();
                };
  /// <summary>
 ///失去焦点事件
  /// </summary>
 private void textBox_LostFocus(object sender, RoutedEventArgs e)
        {
            timerLoseFocuse.Start();

        }

通过定时器解决取消按钮无法获取到获取到焦点的问题,否则点击取消无法执行其点击事件

时间: 2024-08-03 16:10:36

WPF的TextBox的焦点获取与失去焦点的死循环解决方案的相关文章

WPF TextBox 控件获取热键并转为 win32 Keys

WPF 中使用的 Key 对象与 WinForm 中的 Keys 不同,两者的按键枚举对象与物理键的映射关系有功能键上有区别,无法进行类型强制转换.使用 win api 注册热键时,需要将之转换成 win32 的键值,可以使用 KeyInterop.VirtualKeyFromKey(),另外,Keys 可以保存组合鍵,Key 则只是单个按键.Keys 的成员中有个 Modifiers,从下图可以看出 0~15位之外,是用来存放功能键的. 从两张图对比上,可以直观地发现两者的区别. 示例代码:

解决WPF中TextBox文件拖放问题

在WPF中,当我们尝试向TextBox中拖放文件,从而获取其路径时,往往无法成功(拖放文字可以成功).造成这种原因关键是WPF的TextBox对拖放事件处理机制的不同,具体可参考这篇文章Textbox Drag/Drop in WPF,本文只是介绍如何解决这一问题. 解放方法如下: 使用PreviewDragOver和PreviewDrop事件代替DragOver和Drop事件. <TextBox Height="100″ PreviewDragOver="TextBox_Pre

Wpf解决TextBox文件拖入问题、拖放问题

在WPF中,当我们尝试向TextBox中拖放文件,从而获取其路径时,往往无法成功(拖放文字可以成功).造成这种原因关键是WPF的TextBox对拖放事件处理机制的不同, 解放方法如下: 使用PreviewDragOver和PreviewDrop事件代替DragOver和Drop事件. <TextBox Height="100" PreviewDragOver="TextBox_PreviewDragOver" PreviewDrop="TextBox

WPF 浏览文件夹,获取其路径

public void GetPath(System.Windows.Controls.TextBox TB) { FolderBrowserDialog FBD = new FolderBrowserDialog(); FBD.Description = "请选择一个路径"; if(FBD.ShowDialog()==System.Windows.Forms.DialogResult.OK) { TB.Text = FBD.SelectedPath; } } 获取路径代码 priva

[WPF] 动画Completed事件里获取执行该动画的UI对象

原文:[WPF] 动画Completed事件里获取执行该动画的UI对象 昨天群里有位童鞋提出如何在动画完成事件Completed里获取到执行该动画的UI对象. WPF里动画的Completed的本身并不会返回执行动画的UI对象,但我们可以利用附加属性Storyboard.TargetProperty来达到我们想要的效果. 步骤: 1 在执行动画前,先附加属性记录对象 DoubleAnimation ani = new DoubleAnimation(); ani.From = start; an

WPF的TextBox产生内存泄露的情况

前段时间参与了一个WPF编写的项目,在该项目中有这样一个场景:在程序运行过程中需要动态地产生大量文本信息,并追加WPF界面上的一个TextBox的Text中进行显示.编写完之后,运行该项目的程序,发现在产生大量信息之后,发现系统变慢了,打开任务管理器才发现,该项目的程序占用了将近1.5G的内存(天啊!!!这不是一般的耗内存啊!!!).后来通过查资料和探索才发现了WPF的TextBox在追加Text显示文本时会造成内存泄露.下面通过一个小Demo程序来展示一下这个内存泄露. 我的Demo程序很简单

WPF 设置TextBox为空时,背景为文字提示。

<TextBox FontSize="17" Height="26" Margin="230,150,189,0" Name="txt_Account" VerticalAlignment="Top" Foreground="Indigo" TabIndex="0" BorderThickness="1"> <TextBox.Re

C#让TopMost窗体弹出并置顶层但不获取当前输入焦点的终极办法

为了使程序在弹出窗口时置顶层且不获取系统输入焦点,避免影响用户当前的操作,来电通来电弹屏软件尝试过N多种办法,例如:弹出前保存当前焦点窗口句柄,弹出时因为使用TopMost系统默认将焦点交给了弹出窗口,弹出后再将焦点还给弹出前的焦点窗口句柄(C#让窗体置顶弹出但不获取焦点).这种方法貌似解决了问题,但是在弹出的时候还是会打断用户的部分操作.经过我们的不断探索和尝试,终于在Form底层取得了突破,效果很好,和qq的弹窗一样不会打扰用户操作. //声明常量:(释义可参见windows API) co

jquery的blur之后,focus获取不到焦点的解决办法

一:很多童鞋可能会遇到这种情况: jquery的blur之后,focus获取不到焦点. 二:使用场景: 用户填写信息的时候,若邮箱为空,则提示 请填写邮箱,并将光标置于填写邮箱的文本框里,方便用户的再次输入. 想当然的我们会使用jquey的blur()和focus()两个函数来实现上面的需求: $("#email").blur(function(){ if($("#email").val()==''){ alert('请填写您的邮箱'); $("#emai