前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >WPF 弹出 popup 里面的 TextBox 无法输入汉字

WPF 弹出 popup 里面的 TextBox 无法输入汉字

作者头像
林德熙
发布2018-09-18 15:42:39
1.6K0
发布2018-09-18 15:42:39
举报
文章被收录于专栏:林德熙的博客林德熙的博客

这是一个 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 就是需要打开的。

代码语言:javascript
复制
[DllImport("User32.dll")]
public static extern IntPtr SetFocus(IntPtr hWnd);

IntPtr GetHwnd(Popup popup)
{
    HwndSource source = (HwndSource)PresentationSource.FromVisual(popup.Child);
    return source.Handle;
}

private void ShowPopupButtonClick(object sender, RoutedEventArgs e)
{
    ThePopup.IsOpen = true;
    IntPtr handle = GetHwnd(ThePopup);
    SetFocus(handle);
}

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

代码语言:javascript
复制
[DllImport("USER32.DLL")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
 
public static void ActivatePopup(Popup popup)
{
    HwndSource source = (HwndSource)PresentationSource.FromVisual(popup.Child);
    IntPtr handle = source.Handle;
 
    SetForegroundWindow(handle);
}

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

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

代码语言:javascript
复制
 InputMethod.SetIsInputMethodSuspended

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

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


本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档