Hi all,
I'm developing a desktop app using WPF for Windows 8 tablets. Our application need to be in full screen, and need to be able to use touch keyboard for inputs. I've managed to bring the touch keyboard on text box focus in full screen mode. In Landscape mode as soon as the touch on the bottom text box (domain), keyboard pops up, the window size changes and scroll bar comes up. Now I want to see the focused text box to be fully visible as soon as I start typing. In full screen mode (when WindowState="Maximized" WindowStyle="None") its not working. But if I change the style to SingleBorderWindow (removing WindowStyle="None"), it works. But I need the full screen mode :)
Here is my XAML:
<Window x:Class="TestTextClipping.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525" WindowState="Maximized" WindowStyle="None"><Window.Resources><ResourceDictionary Source="/Styles.xaml" /></Window.Resources><ScrollViewer VerticalScrollBarVisibility="Auto"><Grid><Grid.ColumnDefinitions><ColumnDefinition/><ColumnDefinition Width="3*"/><ColumnDefinition/></Grid.ColumnDefinitions><Grid Grid.Column="1"><Grid.RowDefinitions><RowDefinition Height="200"/><RowDefinition/><RowDefinition Height="100"/><RowDefinition/></Grid.RowDefinitions><TextBlock Style="{StaticResource WelcomeMessage}" Text="Welcome to Test App"/><Grid Grid.Row="1" VerticalAlignment="Center"><Grid.ColumnDefinitions><ColumnDefinition/><ColumnDefinition Width="2*"/></Grid.ColumnDefinitions><Grid.RowDefinitions><RowDefinition Height="100"/><RowDefinition Height="100"/><RowDefinition Height="100"/></Grid.RowDefinitions><TextBlock Text="Username" Grid.Row="0" Style="{StaticResource AppLoginTextBlock}"/><TextBlock Text="Password" Grid.Row="1" Style="{StaticResource AppLoginTextBlock}"/><TextBlock Text="Domain" Grid.Row="2" Style="{StaticResource AppLoginTextBlock}"/><TextBox Name="UserName" Grid.Row="0" Grid.Column="1" Style="{StaticResource AppLoginTextBox}"/><PasswordBox Name="PasswordBox" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Stretch" FontSize="40" Height="80" VerticalContentAlignment="Center"/><TextBox Name="Domain" Grid.Row="2" Grid.Column="1" Style="{StaticResource AppLoginTextBox}" /></Grid><Button Grid.Row="2" Content="Login" Margin="0 0 0 0" Style="{StaticResource NextButton}" Click="LoginButtonClickEvent"/><Button Grid.Row="3" Content="Close" Margin="0 0 0 0" Style="{StaticResource NextButton}" Click="CloseButtonClickEvent"/></Grid></Grid></ScrollViewer></Window>
My resource dictionary is:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"><Style x:Key="BaseButtonStyle" TargetType="Button"><Setter Property="FontFamily" Value="Segoe UI" /><Setter Property="FontWeight" Value="Thin" /><Setter Property="Foreground" Value="White" /><Setter Property="HorizontalAlignment" Value="Stretch"/><Setter Property="VerticalAlignment" Value="Stretch"/><Setter Property="VerticalContentAlignment" Value="Center"/><Setter Property="BorderThickness" Value="0"/><Setter Property="BorderBrush" Value="Transparent"/><Setter Property="Focusable" Value="False"/><Setter Property="FontFamily" Value="Segoe UI"/><Setter Property="FontSize" Value="30"/><Setter Property="MaxHeight" Value="200"/></Style><Style x:Key="BaseTextBlockStyle" TargetType="TextBlock"><Setter Property="FontFamily" Value="Segoe UI" /><Setter Property="FontWeight" Value="Thin" /><Setter Property="HorizontalAlignment" Value="Stretch"/><Setter Property="VerticalAlignment" Value="Center"/><Setter Property="TextAlignment" Value="Center"/><Setter Property="FontSize" Value="30"/></Style><Style x:Key="BaseTextBoxStyle" TargetType="TextBox"><Setter Property="HorizontalAlignment" Value="Stretch"/><Setter Property="VerticalAlignment" Value="Center"/><Setter Property="FontFamily" Value="Segoe UI" /><Setter Property="FontWeight" Value="Thin" /><Setter Property="BorderThickness" Value="1"/><Setter Property="FontFamily" Value="Segoe UI"/><Setter Property="FontSize" Value="30"/></Style><Style x:Key="WelcomeMessage" TargetType="TextBlock" BasedOn="{StaticResource BaseTextBlockStyle}"><Setter Property="FontSize" Value="60"/><Setter Property="Foreground" Value="DodgerBlue"/></Style><Style x:Key="AppLoginTextBlock" TargetType="TextBlock" BasedOn="{StaticResource BaseTextBlockStyle}"><Setter Property="FontSize" Value="40"/><Setter Property="TextAlignment" Value="Center"/><Setter Property="VerticalAlignment" Value="Center"/></Style><Style x:Key="AppLoginTextBox" TargetType="TextBox" BasedOn="{StaticResource BaseTextBoxStyle}"><Setter Property="FontSize" Value="40"/><Setter Property="VerticalContentAlignment" Value="Center"/><Setter Property="Height" Value="80"/></Style><Style x:Key="LoginButton" TargetType="Button" BasedOn="{StaticResource BaseButtonStyle}"><Setter Property="Content" Value="Login"/><Setter Property="FontSize" Value="45"/><Setter Property="Height" Value="70"/><Setter Property="Width" Value="200"/><Setter Property="Background" Value="DodgerBlue"/><Setter Property="HorizontalAlignment" Value="Right"/></Style><Style x:Key="FooterButton" TargetType="Button" BasedOn="{StaticResource BaseButtonStyle}"><Setter Property="Height" Value="60"/><Setter Property="Width" Value="150"/><Setter Property="VerticalAlignment" Value="Center"/></Style><Style x:Key="NextButton" TargetType="Button" BasedOn="{StaticResource FooterButton}"><Setter Property="Margin" Value="0 0 50 20"/><Setter Property="Background" Value="LimeGreen"/><Setter Property="HorizontalAlignment" Value="Right"/></Style></ResourceDictionary>
and here is my code behind:
using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace TestTextClipping { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { if (IsWindows8OrNewer()) { DisableWPFTabletSupport(); EnableFocusTracking(); } InitializeComponent(); } bool IsWindows8OrNewer() { var os = Environment.OSVersion; return os.Platform == PlatformID.Win32NT && (os.Version.Major > 6 || (os.Version.Major == 6 && os.Version.Minor >= 2)); } 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 }); } } } } private static void EnableFocusTracking() { int hr = NativeMethods.CoInitializeEx(IntPtr.Zero, NativeMethods.CoInit.ApartmentThreaded); Guid CLSID_InputPanelConfiguration = new Guid("2853ADD3-F096-4C63-A78F-7FA3EA837FB7"); Guid IID_IInputPanelConfiguration = new Guid("41C81592-514C-48BD-A22E-E6AF638521A6"); object inputPanelConfiguration = null; NativeMethods.CoCreateInstance(CLSID_InputPanelConfiguration, null, NativeMethods.CLSCTX.CLSCTX_INPROC_SERVER, IID_IInputPanelConfiguration, out inputPanelConfiguration); int hr1 = (inputPanelConfiguration as IInputPanelConfiguration).EnableFocusTracking(); if (hr >= 0) { NativeMethods.CoUninitialize(); } } private void OnSizeChanged(object sender, SizeChangedEventArgs e) { IInputElement focusedElement = FocusManager.GetFocusedElement(this); if (focusedElement != null) { FrameworkElement frameworkElement = focusedElement as FrameworkElement; if (frameworkElement != null) { frameworkElement.BringIntoView(); } } } private void LoginButtonClickEvent(object sender, RoutedEventArgs e) { } private void CloseButtonClickEvent(object sender, RoutedEventArgs e) { Application.Current.Shutdown(0); } } [ComImport()] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] [Guid("41C81592-514C-48BD-A22E-E6AF638521A6")] public interface IInputPanelConfiguration { int EnableFocusTracking(); } public static class NativeMethods { public enum CoInit { ApartmentThreaded = 0x2, } [DllImport(@"ole32.dll")] internal static extern int CoInitializeEx(IntPtr reserved, CoInit coInit); [DllImport("ole32.dll", ExactSpelling = true, PreserveSig = false)] [return: MarshalAs(UnmanagedType.Interface)] internal static extern void CoCreateInstance( [In, MarshalAs(UnmanagedType.LPStruct)] Guid rclsid, [MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter, CLSCTX dwClsContext, [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object rReturnedComObject); [DllImport("ole32.dll")] internal static extern void CoUninitialize(); [Flags] public enum CLSCTX : uint { CLSCTX_INPROC_SERVER = 0x1, } } }
Does anybody have any idea?