Подтвердить что ты не робот

Как заставить управление вводами WPF показывать виртуальную клавиатуру, когда она попадает в сенсорный экран

Для нашего приложения WPF, когда он работает на сенсорном экране (Surface Pro.etc), элемент управления TextBox/PasswordBox не может отображать виртуальную клавиатуру, когда они сосредоточиться.

Любой хороший способ реализовать эту функцию в WPF?


Обновлено:

то, чего мы хотим достичь, наконец-то выглядит следующим образом:

Если пользователь запускает приложение на ПК, нам не нужна эта функция, а это означает, что у пользователя есть физическая клавиатура, мы ничего не делаем, как обычное приложение WPF, запущенное на ПК.

Если пользователь работает на Surface Pro, когда он нажимает кнопку TextBox, встроенная виртуальная клавиатура может отображаться и которая должна быть удобной для пользователя, например, клавиатура никогда не будет закрываться элемент ввода.


Обновлено 2:

Итак, WPF не может легко установить какое-либо свойство для реализации этой функции? На мой взгляд, эта функция должна быть встроена в WPF, я не понимаю, почему я не могу найти простой способ достичь.

4b9b3361

Ответ 1

Попробуйте это,

Сначала проверьте наличие физической клавиатуры:

KeyboardCapabilities keyboardCapabilities = new Windows.Devices.Input.KeyboardCapabilities();
return  keyboardCapabilities.KeyboardPresent != 0 ? true : false;

Если вы не найдете физическую клавиатуру, используйте встроенную виртуальную клавиатуру окон:

Process.Start(Environment.GetFolderPath(Environment.SpecialFolder.System) + Path.DirectorySeparatorChar + "osk.exe");

Получите помощь отсюда: ссылка 1 ссылка 2

Ответ 2

Я опубликовал образец того, как запускать сенсорную клавиатуру в приложениях WPF, когда пользователь нажимает на текстовое поле, здесь:

http://code.msdn.microsoft.com/Enabling-Windows-8-Touch-7fb4e6de

Это то, над чем я работал много месяцев, я рад наконец внести этот пример в наше сообщество. Пожалуйста, дайте мне знать, есть ли какие-либо вопросы, предложения, проблемы и т.д. В поле Q & A

Ответ 3

Это решение очень просто: http://code.msdn.microsoft.com/windowsapps/Enabling-Windows-8-Touch-7fb4e6de

Шаги подробно описаны в приведенной выше ссылке, вот короткая версия:

  • Добавить ссылку UIAutomationClient
  • Использовать IFrameworkInputPane из управляемого кода (DLL по ссылке или конвертировать inputpanelconfiguration.idl в DLL, см. шаги ниже)
  • Создайте новый класс InkInputHelper для отключения поддержки чернил (код ниже)
  • Вызов InkInputHelper.DisableWPFTabletSupport(); из MainWindow конструктора или аналогичного
  • Добавить using System.Windows.Interop;
  • Добавить в MainWindow_Loaded или подобное:

        System.Windows.Automation.AutomationElement asForm =
        System.Windows.Automation.AutomationElement.FromHandle(new WindowInteropHelper(this).Handle);
        InputPanelConfigurationLib.InputPanelConfiguration inputPanelConfig = new InputPanelConfigurationLib.InputPanelConfiguration();
        inputPanelConfig.EnableFocusTracking();
    

Чтобы преобразовать inputpanelconfiguration.idl в DLL

В Windows 8.1: c:\Program Files (x86)\Windows Kits\8.1\Include\um\inputpanelconfiguration.idl

Чтобы создать DLL из IDL, выполните следующие действия:

  • Запустите командную строку
  • Используйте средство компиляции MIDL для создания TLB файла библиотеки типов
    • Пример: midl /tbld {filename}
  • Используйте инструмент TLBIMP для преобразования вышеприведенной библиотеки типов (TLB файла) в DLL, которую .NET может использовать, выполнив следующую команду
    • Пример: TLBIMP.exe InputpanelConfiguration.tlb /publickey:{pathToKey} /delaysign

Класс InkInputHelper:

using System;
using System.Reflection;
using System.Windows.Input;

namespace ModernWPF.Win8TouchKeyboard.Desktop
{
public static class InkInputHelper
{
    public static void DisableWPFTabletSupport()
    {
        // Get a collection of the tablet devices for this window.  
        TabletDeviceCollection devices = System.Windows.Input.Tablet.TabletDevices;

        if (devices.Count > 0)
        {
            // Get the Type of InputManager.
            Type inputManagerType = typeof(System.Windows.Input.InputManager);

            // Call the StylusLogic method on the InputManager.Current instance.
            object stylusLogic = inputManagerType.InvokeMember("StylusLogic",
                        BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.NonPublic,
                        null, InputManager.Current, null);

            if (stylusLogic != null)
            {
                //  Get the type of the stylusLogic returned from the call to StylusLogic.
                Type stylusLogicType = stylusLogic.GetType();

                // Loop until there are no more devices to remove.
                while (devices.Count > 0)
                {
                    // Remove the first tablet device in the devices collection.
                    stylusLogicType.InvokeMember("OnTabletRemoved",
                            BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.NonPublic,
                            null, stylusLogic, new object[] { (uint)0 });
                }
            }
        }
    }
}
}

Это должно сработать. Опять же, гораздо лучшая информация и загружаемый образец в ссылке. Я только копировал вставку основ для целей архивирования.

Ответ 4

Я создал библиотеку для автоматизации всего, что касается интеграции TabTip в приложении WPF.

Вы можете получить его на nuget, и после этого все, что вам нужно, это простая конфигурация в логике запуска приложений:

TabTipAutomation.BindTo<TextBox>();

Вы можете связать логику автоматизации TabTip с любым UIElement. Виртуальная клавиатура откроется, когда любой элемент указанного типа получит фокус, и он закроется, когда элемент потеряет фокус. Не только это, но TabTipAutomation переместит UIElement (или Window) в представление, так что TabTip не будет блокировать сфокусированный элемент.

Для получения дополнительной информации обратитесь к сайту проекта.

Ответ 5

Я видел это в сеансе TechEd, вам нужно сначала отключить поддержку Inking (DisableWPFTabletSupport), затем вы можете создать InputPanelConfiguration (AutomationElement.FromHandle(новый WindowsInteropHelper (this).Handle) и вызвать EnableFocusTracking.

DisableWPFTabletSupport: http://msdn.microsoft.com/en-us/library/ee230087.aspx

EnableFocusTracking: http://msdn.microsoft.com/en-us/library/windows/desktop/jj126268(v=vs.85).aspx

Ответ 6

 public static class InkInputHelper
    {
        public static void DisableWPFTabletSupport()
        {
            // Get a collection of the tablet devices for this window.  
            TabletDeviceCollection devices = System.Windows.Input.Tablet.TabletDevices;

            if (devices.Count > 0)
            {
                // Get the Type of InputManager.
                Type inputManagerType = typeof(System.Windows.Input.InputManager);

                // Call the StylusLogic method on the InputManager.Current instance.
                object stylusLogic = inputManagerType.InvokeMember("StylusLogic",
                            BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.NonPublic,
                            null, InputManager.Current, null);

                if (stylusLogic != null)
                {
                    //  Get the type of the stylusLogic returned from the call to StylusLogic.
                    Type stylusLogicType = stylusLogic.GetType();

                    // Loop until there are no more devices to remove.
                    while (devices.Count > 0)
                    {
                        // Remove the first tablet device in the devices collection.
                        stylusLogicType.InvokeMember("OnTabletRemoved",
                                BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.NonPublic,
                                null, stylusLogic, new object[] { (uint)0 });
                    }
                }
            }
        }
    }

используйте этот класс, чтобы определить, есть ли физическая клавиатура или аналогичный способ, который может лучше соответствовать вашим потребностям.

Я использовал этот класс, чтобы открывать и закрывать клавиатуру там, где я хотел.

 class KeyboardManager
    {

        public static void LaunchOnScreenKeyboard()
        {
            var processes = Process.GetProcessesByName("osk").ToArray();
            if (processes.Any())
                return;
            string keyboardManagerPath = "KeyboardExecuter.exe";
           Process.Start(keyboardManagerPath);
        }

        public static void KillOnScreenKeyboard()
        {
            var processes = Process.GetProcessesByName("osk").ToArray();
            foreach (var proc in processes)
            {
                proc.Kill();
            }
        }
        public static void killTabTip()
        {
            var processes = Process.GetProcessesByName("TabTip").ToArray();
            foreach (var proc in processes)
            {
                proc.Kill();
            }
        }

        public static void LaunchTabTip()
        {
            Process.Start("TabTip.exe");
        }
    }

помните следующее: Я добавил копию обоих osk.exe AND tabtip.exe. добавив, что в моей программе решена проблема, когда либо tabtip, либо osk не будут работать с 32/64 бит.

osk - клавиатура, tabtip - это закрепленная версия. keyboardexecuter - это программа, которую я сделал, которая используется в качестве резервного метода.

note * В настоящее время я не могу проверить это на устройстве с сенсорным экраном. вы должны попробовать это самостоятельно.

для этого, чтобы все работало правильно, я использовал этот код в моем главном окне:

public int selectedTableNum;
        public MainWindow()
        {
            InitializeComponent();

            Loaded += MainWindow_Loaded;

            // Disables inking in the WPF application and enables us to track touch events to properly trigger the touch keyboard
            InkInputHelper.DisableWPFTabletSupport();
            //remove navigationbar
            Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new Action(() =>
            {
                var navWindow = Window.GetWindow(this) as NavigationWindow;
                if (navWindow != null) navWindow.ShowsNavigationUI = false;
            }));


            KeyboardManager.LaunchTabTip();

        }

        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            //Windows 8 API to enable touch keyboard to monitor for focus tracking in this WPF application
            InputPanelConfiguration cp = new InputPanelConfiguration();
            IInputPanelConfiguration icp = cp as IInputPanelConfiguration;
            if (icp != null)
                icp.EnableFocusTracking();
            mainFrame.Content = new LoginPage();
        }
        //public bool HasTouchInput()
        //{
        //    foreach (TabletDevice tabletDevice in Tablet.TabletDevices)
        //    {
        //        //Only detect if it is a touch Screen not how many touches (i.e. Single touch or Multi-touch)
        //        if (tabletDevice.Type == TabletDeviceType.Touch)
        //            return true;
        //    }

        //    return false;
        //}

i включил комментарии, потому что может быть полезно кому-то, если есть ошибка.

конфигурация входной панели:

[Guid("41C81592-514C-48BD-A22E-E6AF638521A6")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IInputPanelConfiguration
{
    /// <summary>
    /// Enables a client process to opt-in to the focus tracking mechanism for Windows Store apps that controls the invoking and dismissing semantics of the touch keyboard.
    /// </summary>
    /// <returns>If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.</returns>
    int EnableFocusTracking();
}

[ComImport, Guid("2853ADD3-F096-4C63-A78F-7FA3EA837FB7")]
class InputPanelConfiguration
{
}

Надеюсь, это поможет будущим посетителям этого вопроса.

Ответ 8

Самый простой вариант, когда не требуется вывод SecureString, - использовать TextBox и использовать что-то вроде Wingdings в качестве шрифта.