Jak zobrazit dotykovou klávesnici při práci s TextBoxy ve WPF

Development General WPF

9 years ago

Aktualizováno - listopad 2016 - .NET Framework 4.6.2 Aplikace ve WPF (Windows Presentation Foundation) mají ve světě dotykových obrazovek zatím trochu těžký život. V případě WinRT aplikací se panel s dotykovou obrazovkou zobrazí automaticky, kdy je aktivováno kterékoliv textové pole v aplikaci, aby uživatel nemusel přerušovat své workflow a všechny úkony mohl provádět jen dotykem. Pro klasické desktopové aplikace je ale situace trochu komplikovanější - textová pole klávesnici automaticky nezobrazí a je tak na uživateli, aby ji otevřel sám. A to je nepraktické.

TouchKeyboard

Hej! Jak tě zobrazím ve své WPF aplikaci?

Pro tento problém existují dvě různá řešení.

Trošku hackovací řešení

První řešení vyžaduje trochu hraní se systémem. Nejdříve je nutné vypnout podporu pro použití pera jako vstupního zařízení v naší aplikaci a následně je možné vynutit, aby se textová pole chovala stejně jako ve WinRT pomocí nativních Windows API. To samozřejmě zahrnuje nutnost provést COM import příslušných nativních funkcí systému. Celý proces je velmi dobře popsán zde na blogu Briana Lagunase a doporučuji vám jej vyzkoušet. Pokud vám řešení bude vyhovovat, skvěle! Nevýhodou tohoto řešení, kterou jsem náhodou objevil, je fakt, že vypnutí podpory pera z nějakého důvodu zablokuje možnost dotykového "scrollování" skrz ovladací prvky typu ListBox. Kterýkoliv pokus o scrollování tímto způsobem způsobí volání události ItemClick na položkách seznamu, kterých se dotkneme. Uživatel pak může scrollovat pouze malým posuvníkem seznamu, který je pro dotyk nevhodný.

Jednoduchá, ale více manuální cesta

Abychom obešli problémy, které přícházejí po vypnutí podpory pera ve WPF aplikaci (případně pokud tuto podporu vyžadujeme), můžeme jít na celý problém jednodušší cestou, ač s trochu méně automaticky. Vytvoříme vlastní implementaci TextBoxu:

public class TouchEnabledTextBox : TextBox
{
    public TouchEnabledTextBox()
    {
        this.GotTouchCapture += TouchEnabledTextBox_GotTouchCapture;
    }

    private void TouchEnabledTextBox_GotTouchCapture(object sender, System.Windows.Input.TouchEventArgs e)
    {
        string touchKeyboardPath = @"C:\Program Files\Common Files\Microsoft Shared\Ink\TabTip.exe";        
        Process.Start( touchKeyboardPath );
    }
}

Jak to funguje? Když TextBox získá focus po dotyku uživatele, je zavolána událost GotTouchCapture. V zpracování této události můžeme manuálně spustit proces dotykové klávesnice. Ta je totiž normální spustitelnou aplikací na cestě "C:\Program Files\Common Files\Microsoft Shared\Ink\TabTip.exe". Toto řešení je velmi jednoduché a nevyžaduje žádné explicitní "hackování". Jedinou nevýhodou je, že vy jako vývojář musíte vždy pamatovat, abyste namísto klasického TextBoxu používali tuto modifikovanou verzi pokaždé, kdy je vyžadováno správné dotykové chování.

Ukončení procesu

Logickým rozšířením tohoto řešení je zabití procesu dotykové klávesnice ve chvíli, kdy ji již nepotřebujeme - tedy když vstupní pole ztratí focus. Metoda Process.Start( string ) vrací instanci třídy Process, která má instanční metodu Kill() . Tato metoda ukončí proces jež instance představuje. Nejprve potřebujeme zajistit, abychom k instanci procesu měli přístup:

//uvnitř definice třídy
private Process _touchKeyboardProcess = null;

//nahraďte řádek Process.Start následujícím
_touchKeyboardProcess = Process.Start( touchKeyboardPath );

Nyní jen napojíme událost LostFocus:

//tento řádek přidejte na konec konstruktoru třídy
this.LostFocus += TouchEnabledTextBox_LostFocus;

//přidejte tuto instanční metodu naší třídě
private void TouchEnabledTextBox_LostFocus( object sender, RoutedEventArgs eventArgs ){
   if ( _touchKeyboardProcess != null ) 
   {
      _touchKeyboardProcess.Kill();
      //vynulovat instanci ukazující na nyní neplatný proces
      _touchKeyboardProcess = null;
   }
}

Aktualizováno - co Windows 10?

Ve Windows 10 se tento problém stává spíše kosmetickou vadou díky novému Režimu tabletu.

Režim tabletu

tablet-modeNejnovější verze Windows přináší nový Režim tabletu, do kterého se lze přepnout pomocí tlačítka v Centru akcí nebo přes aplikaci Nastavení. Přestože tento mód někteří vidí jako nevýhodu oproti Windows 8.1, umožňuje výrazně intuitivnější integraci nových Windows Store aplikací a klasických desktopových aplikací. Každá aplikace se ve výchozí podobě spouští v režimu celé obrazovky, ale je stále možné spouštět dvě aplikace vedle sebe. Jednou z velmi pěkných výhod Režimu tabletu je fakt, že dotyková klávesnice na obrazovce se zobarzuje automaticky, když jakýkoliv textový prvek dostane focus, a to nezávisle na typu aplikace. Tímto můžete přenechat kontrolu nad zobrazením klávesnice systému samotnému a usnadnit si tak výrazně práci. Jedinou nevýhodou je to, že i přes talbetové zobrazení klávesnice na rozdíl od Windows Store aplikací překrývá obsah okna nad kterým je zobrazena a neposune jej nahoru, ani ve chvíli, kdy je připnuta ke spodní straně obrazovky. Může se tak stát, že kontextová menu a drop-down seznamy skončí pod klávesnicí a uživatel je tak nucen ji pro pokračování manuálně uzvařít.

Mimo Režim tabletu

Ale co v případě, že Režim tabletu z nějakého důvodu nechcete nebo nemůžete použít? Jedno nenápadné nastavení nás zachrání! Otevřete aplikaci Nastavení, přejděte do sekce Zařízení a vyberte Psaní - zde skrolujte dolů a úplně na konci najdete nastavení, které je ve výchozím stavu vypnuto (bohužel nechápu z jakého důvodu) - po povolen tohoto nastavení se dotyková klávesnice zobrazí automaticky ve chvíli, kdy se prstem spustí zadávání textu a není připojena žádná klávesnice. Toto je perfektní řešení pro většinu případů a používání klasických aplikací na dotykovém zařízení to dělá intuitivním a konzistentním.touch

Aktualizováno - .NET Framework 4.6.2

V srpnu 2016 Microsoft oznámil novou aktualizaci .NET Framework 4.6.2. Kromě velmi užitečného rozšíření WPF o podporu Per-Monitor DPI tato aktualizace také adresovala problém s klávesnicí na dotykovém zařízení. WPF aplikace cílené na novou verzi frameworku podporují automatickou invokaci a skrytí dotykové klávesnice stejně tak jako je to u nových UWP aplikací, takže výše uvedená řešení již nejsou pro nové aplikace nutná. softkeyboard