title author date CreateTime categories
WPF 弹出 popup 里面的 TextBox 无法输入汉字
lindexi
2018-12-21 18:10:30 +0800
2018-2-13 17:23:3 +0800
WPF

这是一个 wpf 的bug,在弹出Popup之后,如果 Popup 里面有 TextBox ,这时无法在里面输入文字。

因为 Popup 的句柄具有 WS_EX_NOACTIVATE 的特性,所以 Popup 是无法获得焦点。在微软的系统,所有的窗口、控件都是有句柄,句柄就是一个指针,获得他才知道是哪个控件。

古老的输入法就是通过判断获得焦点的句柄是支持输入和判断他需要什么输入,如果在 win7 的搜狗,就是这样判断,于是搜狗很难在 Popup 的 TextBox 输入文字。

这个问题实际很好解决,最简单的方法是把程序修改为 .net 4.6.2 以上,这个 bug 已经在 .net 4.6.2 修复了。或者升级到 win10 系统。如果刚好两个方法都不能使用,那么通过代码也可以解决。

解决的方法是让输入法知道控件的句柄,这需要一个 win32 的 dll ,传说中的 User32.dll ,这个dll有SetFocus这个方法,请通过下面的代码在Popup打开时调用。代码的 ThePopup 就是需要打开的。

  1. [DllImport("User32.dll")]
  2. public static extern IntPtr SetFocus(IntPtr hWnd);
  3.  
  4. IntPtr GetHwnd(Popup popup)
  5. {
  6. HwndSource source = (HwndSource)PresentationSource.FromVisual(popup.Child);
  7. return source.Handle;
  8. }
  9.  
  10. private void ShowPopupButtonClick(object sender, RoutedEventArgs e)
  11. {
  12. ThePopup.IsOpen = true;
  13. IntPtr handle = GetHwnd(ThePopup);
  14. SetFocus(handle);
  15. }

这是一个简单的方法。当然还有另一个方法,使用SetForegroundWindow方法。

  1. [DllImport("USER32.DLL")]
  2. [return: MarshalAs(UnmanagedType.Bool)]
  3. public static extern bool SetForegroundWindow(IntPtr hWnd);
  4.  
  5. public static void ActivatePopup(Popup popup)
  6. {
  7. HwndSource source = (HwndSource)PresentationSource.FromVisual(popup.Child);
  8. IntPtr handle = source.Handle;
  9.  
  10. SetForegroundWindow(handle);
  11. }

参见:https://www.codeproject.com/Questions/184429/Text-box-is-not-working-in-WPF-Popup

如果发现使用了我的方法还是无法输入,那么需要看一下 TextBox 是否禁用输入法。

  1. InputMethod.SetIsInputMethodSuspended

和这个类的其他属性都可以设置输入法,请尝试修改他的值。

这个问题已经反馈 https://connect.microsoft.com/VisualStudio/feedback/details/389998/wpf-popup-messes-with-ime-switching ,微软已经修复

修复在 Popup 输入法不跟随

在 Popup 里的 TextBox 输入可能出现输入法未跟随编辑框,这时需要调用 Win32 的方法

  1. [DllImport("User32.dll")]
  2. public static extern IntPtr SetFocus(IntPtr hWnd);
  3.  
  4. IntPtr GetHwnd(Popup popup)
  5. {
  6. HwndSource source = (HwndSource)PresentationSource.FromVisual(popup.Child);
  7. return source.Handle;
  8. }

在 TextBox 获得焦点的时候调用下面代码

  1. xxPopup.GotFocus += Popup_GotFocus;
  2.  
  3. private void Popup_GotFocus(object sender, RoutedEventArgs e)
  4. {
  5. // WPF BUG Fix:TextBox 在 Popup 中,IME 备选框不跟随
  6. Win32.SetFocus(GetHwnd(RenamePopup.Child));
  7. }

在 WinForms 弹出的 WPF 的 TextBox 无法输入问题

刚刚 Siberia 问了我一个问题,为什么 WinForms 弹出的 WPF 的文本框无法输入数字,但是可以输入其他的内容

一开始我认为的是绑定的问题,如果一个控件绑定了另一个控件,或者有后台代码绑定,有另一个控件绑定了输入框都有方法让用户输入的数字不显示

如果是我在调试,我会先拿到 TextChanged 事件,看是不显示还是没有接收到输入

另外需要判断当前的焦点是否在 TextBox 上

按照这个方法会发现有焦点,但是没有 TextChanged 收到输入,这时因为 WinForms 弹出的 WPF 程序消息循环的键盘事件的问题,对于中文的输入,有输入法在 HasKeyboardFocusCore 拿到输入,但是如果数字不经过输入法就在 WinForms 收到数字

解决的方法是调用 EnableModelessKeyboardInterop 传入 WPF 就可以

  1. Window winWPF = new Window();  //WinWPF为想要显示的WPF窗体。
  2. System.Windows.Forms.Integration.ElementHost.EnableModelessKeyboardInterop(winWPF);     
  3. winWPF.Show(); 

WPF 禁用TextBox的触摸后自动弹出虚拟键盘 - 唐宋元明清2188 - 博客园

解决Winform中弹出WPF窗体不能在文本框中输入的问题 - 飞鹰的专栏 - CSDN博客

Windows 窗体和 WPF 互操作性输入 - 小而美 - CSDN博客

ElementHost.EnableModelessKeyboardInterop(Window) Method (System.Windows.Forms.Integration)

2018-12-21-WPF-弹出-popup-里面的-TextBox-无法输入汉字的更多相关文章

  1. 在指定控件位置弹出popup window

    先看效果图 黄色的就是弹出的popup window 首先自定义一个view用来显示,文件名为layout_my_view.xml <?xml version="1.0" e ...

  2. WPF弹出进度条

    环境:vs2015 ,.net 4.6 源码地址:https://pan.baidu.com/s/1FoujUMst1luomPf0ZfCLUQ 提取码:trzj 说明: 1.进度条是在winFrom ...

  3. WPF弹出带蒙板的消息框

    效果图 思路 拿到父级窗体的内容,放入一个容器里,再在容器里放入一个半透明层.将整个容器赋给父级窗体的内容. 关闭时反向操作. 代码 消息窗弹出时 /// <summary> /// 弹出 ...

  4. WPF 弹出UserControl

    UserControl正常情况下是不能被弹出的,而编写好的UserControl页面,为了查看效果,又需要弹出. 为了解决这个问题,UserControl需要一个Windows来接收. var win ...

  5. 自动化测试-12.selenium的弹出框处理

    前言 不是所有的弹出框都叫alert,在使用alert方法前,先要识别出到底是不是alert.先认清楚alert长什么样子,下次碰到了,就可以用对应方法解决. alert\confirm\prompt ...

  6. 2018.12.21 bzoj3238: [Ahoi2013]差异(后缀自动机)

    传送门 后缀自动机好题. 题意: 做法:samsamsam 废话 考虑翻转字串,这样后缀的最长公共前缀等于前缀的最长公共后缀. 然后想到parentparentparent树上面两个串的最长公共后缀跟 ...

  7. WPF弹出取消确定框

    MessageBoxResult dr = MessageBox.Show("是否在"+ConfigHelper.GetAppSetting("SourceDBName& ...

  8. WPF弹出对话确认框

    MessageBoxResult mr = CMessageBox.ShowQuestionMessage("点击“是”继续,点击“否”取消.", "确认删除?" ...

  9. 2018/12/21:Date类

    1.Date类 getDate()返回一个月的某一天 1-31 getDay()返回一周的某一天 getFullyear()返回四位数的年份 getMonth()返回月份 比实际情况小 1 0代表1月 ...

  10. 2018/12.21:函数this的指向

    1.     解决函数内this指向 1.        可以在函数外提前声明变量 _this/that=this 2.        通过apply和call 来修改函数内的this指向 (1)   ...

随机推荐

  1. webgoat的构建

    如何打开webgoat 1.ctrl+r  打开命令 2.cmd 打开命令编辑器 3.我的webgoat保存在E:/安全软件/webgoat-container-7.0.1-war-exec下 4.在 ...

  2. thinkphp 运算符

    我们可以对模板输出使用运算符,包括对“+”“ –” “*” “/”和“%”的支持. 大理石平台厂家 例如: 运算符 使用示例 + {$a+$b} - {$a-$b} * {$a*$b} / {$a/$ ...

  3. thinkphp url大小写

    系统默认的规范是根据URL里面的模块名.控制器名来定位到具体的控制器类的,从而执行控制器类的操作方法. 以URL访问 http://serverName/index.php/Home/Index/in ...

  4. retired!

    退役啦!估计不会再更新了,终于在大四拿到了icpc,ccpc,省赛,邀请赛金,也算是圆满了!

  5. 线性dp,后缀处理——cf1016C好题

    绝对是好题 #include<bits/stdc++.h> using namespace std; #define maxn 300005 #define ll long long ll ...

  6. VS2010-MFC(常用控件:树形控件Tree Control 上)

    转自:http://www.jizhuomi.com/software/200.html 前面两节讲了列表视图控件List Control,这一节开始介绍一种特殊的列表--树形控件Tree Contr ...

  7. spss logistic回归分析结果如何分析

    spss logistic回归分析结果如何分析 如何用spss17.0进行二元和多元logistic回归分析 一.二元logistic回归分析 二元logistic回归分析的前提为因变量是可以转化为0 ...

  8. Java 面试题经典 77 问(含答案)!

    金三银四了,3月底,4月初,找工作换单位的黄金时期.4月初将会有有一大批职场人士流动... 作为Java开发码农的你是不是也在蠢蠢欲动,或者已经搞了几轮车轮战了? 我们为大家准备了 77 道经典 Ja ...

  9. unittest零碎知识

    给unittest传值: class TesCase(unittest.TestCase): # k1 = expect = msg = None # requests的返回结果和用例的预期值 def ...

  10. 注解@Qualifier@Primary

    在Controller中需要注入service那么我的这个server有两个实现类如何区分开这两个impl呢 根据注入资源的注解不同实现的方式有一点小小的区别 在Controller中使用 @Auto ...