You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF中禁用Win10自动弹出屏幕键盘,实现点击文本框唤出

手动控制WPF中文本框触发Win10屏幕键盘的解决方案

我之前也踩过WPF和Win10系统自带屏幕键盘兼容的大坑——明明在系统设置里开了非平板模式自动弹出,但在多文本框的WPF应用里要么闪一下就消失,要么完全没反应,触摸屏设备上这个问题尤其突出。后来索性放弃系统自动逻辑,手动控制键盘的弹出和关闭,亲测稳定好用,分享给你:

核心思路

直接调用Windows自带的屏幕键盘程序osk.exe,通过WPF文本框的焦点事件来触发启动/前置操作,同时处理重复启动、窗口遮挡等细节问题。

实现步骤

1. 绑定文本框的焦点事件

在XAML里给需要触发键盘的文本框绑定GotFocus(获得焦点)和LostFocus(失去焦点)事件:

<Window x:Class="WpfOskDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="WPF屏幕键盘测试" Height="450" Width="800">
    <StackPanel Margin="20">
        <TextBox x:Name="txtUsername" GotFocus="TextBox_GotFocus" LostFocus="TextBox_LostFocus" Margin="0 0 0 10" />
        <TextBox x:Name="txtPassword" GotFocus="TextBox_GotFocus" LostFocus="TextBox_LostFocus" Margin="0 0 0 10" />
        <TextBox x:Name="txtAddress" GotFocus="TextBox_GotFocus" LostFocus="TextBox_LostFocus" />
    </StackPanel>
</Window>

2. 后台代码实现键盘控制

在C#后台代码中处理事件,实现启动、前置、关闭屏幕键盘的逻辑,同时加入触摸屏设备判断(可选):

using System;
using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Input;

namespace WpfOskDemo
{
    public partial class MainWindow : Window
    {
        private Process _oskProcess;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void TextBox_GotFocus(object sender, RoutedEventArgs e)
        {
            // 可选:仅在触摸屏设备上触发,非触摸屏设备跳过
            if (!Tablet.TabletDevices.OfType<TabletDevice>().Any(t => t.Type == TabletDeviceType.Touch))
            {
                return;
            }

            // 检查键盘是否已运行
            if (_oskProcess == null || _oskProcess.HasExited)
            {
                try
                {
                    // 启动屏幕键盘,使用ShellExecute避免权限问题
                    var startInfo = new ProcessStartInfo
                    {
                        FileName = "osk.exe",
                        UseShellExecute = true,
                        WindowStyle = ProcessWindowStyle.Normal
                    };
                    _oskProcess = Process.Start(startInfo);
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"启动屏幕键盘失败:{ex.Message}");
                }
            }
            else
            {
                // 键盘已运行,将其前置显示(避免被其他窗口遮挡)
                if (_oskProcess.MainWindowHandle != IntPtr.Zero)
                {
                    User32.SetForegroundWindow(_oskProcess.MainWindowHandle);
                }
            }
        }

        private void TextBox_LostFocus(object sender, RoutedEventArgs e)
        {
            // 检查是否还有其他文本框处于焦点状态,没有则关闭键盘
            var focusedTextBox = Keyboard.FocusedElement as TextBox;
            if (focusedTextBox == null)
            {
                _oskProcess?.CloseMainWindow();
                _oskProcess?.WaitForExit();
                _oskProcess = null;
            }
        }
    }

    // 引入User32.dll的API用于窗口前置
    internal static class User32
    {
        [System.Runtime.InteropServices.DllImport("user32.dll")]
        internal static extern bool SetForegroundWindow(IntPtr hWnd);
    }
}

关键注意事项

  • 避免重复启动:一定要检查_oskProcess的状态,防止多次打开屏幕键盘窗口。
  • 权限兼容:使用UseShellExecute = true启动osk.exe,避免管理员权限运行应用时出现启动失败的问题。
  • 窗口遮挡处理:通过SetForegroundWindow确保键盘窗口显示在最上层,不会被WPF窗口挡住。
  • 触摸屏判断:如果你的应用只针对触摸屏设备,可以去掉触摸屏检测的逻辑,直接触发键盘。

内容的提问来源于stack exchange,提问作者lentinant

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:18:16