WindowStyle None 和触摸输入
WindowStyle None and touch input
在Windows10中,当使用像Surface这样的触摸设备时,在未最大化window中触摸像TextBox这样的输入控件会导致整个window向上移动,因此用户可以看到他正在输入的内容(如果键盘已停靠)。但是当 WindowStyle is set to none
时不会发生。为什么它没有发生? 我们的应用程序需要这种行为。它可以在 WindowStyle=None 上修复吗?我发现它与它的风格无关 - 没有内置触发器或其他东西。我们需要 WindowsStyle=None 自定义关闭按钮栏(我们希望栏是透明的,只有按钮是可见的)。
采用网格布局将其分成 3 行,并将一个自定义按钮添加到行的右上角,然后在该按钮事件处理程序上执行 Window 关闭代码和相同的最小化
并设置 Window样式=none
我遇到了一个类似的问题,试图让我的应用程序对 Windows 10 触摸键盘的存在做出正确的反应,但它不会这样做,除非 WindowStyle
被设置为其他东西比 None
.
挣扎了一段时间,直到我决定自己尝试设置 Window 的样式并手动删除边框,这让我发现了 WindowChrome
class。
WindowChrome documentation提到了关于WindowStyle="None"
的这个:
One way to customize the appearance of a WPF application window is to set the Window.WindowStyle property to None. This removes the non-client frame from the window and leaves only the client area, to which you can apply a custom style. However, when the non-client frame is removed, you also lose the system features and behaviors that it provides, such as caption buttons and window resizing. Another side effect is that the window will cover the Windows taskbar when it is maximized. Setting WindowStyle.None enables you to create a completely custom application, but also requires that you implement custom logic in your application to emulate standard window behavior.
看来是因为缺少 non-client(或 OS)框架,导致应用程序无法对键盘的存在做出反应。
解决方案是实现自定义 WindowChrome
。可以这样做:
<Window x:Class="WpfApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:shell="clr-namespace:System.Windows.Shell;assembly=PresentationFramework"
Title="MainWindow" Height="350" Width="525" WindowState="Maximized">
<shell:WindowChrome.WindowChrome>
<shell:WindowChrome NonClientFrameEdges="None"
UseAeroCaptionButtons="False"
CornerRadius="0"
GlassFrameThickness="0"
ResizeBorderThickness="0"
CaptionHeight="0" />
</shell:WindowChrome.WindowChrome>
<Grid Background="DarkOrange">
<TextBlock Text="TEST" VerticalAlignment="Center"
HorizontalAlignment="Center" FontSize="32" />
</Grid>
</Window>
如果您绝对必须使用 WindowStyle="None"
,那么根据上面的文档,Window 逻辑必须是自定义的。幸运的是,Microsoft 提供了一个很好的示例,说明如何编写自定义逻辑以对触摸键盘的存在做出反应:See this link.
如果您想将自己的自定义按钮添加到标题栏,请查看 this excellent post 关于样式化您的 Window。
希望对您有所帮助!
更新:
经过进一步调查,发现此解决方案仅适用于 Windows 10 版本 1903。当我们在生产中使用的 1809 上尝试时,它没有用。原因显然是微软已经改变了应用程序在 full-screen 模式下对触摸键盘的反应方式。
这可以通过在 Windows 的两个版本中最大化 Explorer 来轻松测试,并查看在 1809 年如何没有发生任何事情,但在 1903 年 Window 被调整大小以适应剩余的 [=62] =] 在屏幕上。
我注意到的另一件重要事情是,当我从 Visual Studio 启动应用程序时(无论是否连接调试器),当触摸屏出现时,UI 没有反应它, 但是 当我 运行 来自资源管理器的可执行文件时,它确实可以工作。所以在我的测试中,我总是会构建,然后转到 bin\Debug,然后从那里启动 exe。
在Windows10中,当使用像Surface这样的触摸设备时,在未最大化window中触摸像TextBox这样的输入控件会导致整个window向上移动,因此用户可以看到他正在输入的内容(如果键盘已停靠)。但是当 WindowStyle is set to none
时不会发生。为什么它没有发生? 我们的应用程序需要这种行为。它可以在 WindowStyle=None 上修复吗?我发现它与它的风格无关 - 没有内置触发器或其他东西。我们需要 WindowsStyle=None 自定义关闭按钮栏(我们希望栏是透明的,只有按钮是可见的)。
采用网格布局将其分成 3 行,并将一个自定义按钮添加到行的右上角,然后在该按钮事件处理程序上执行 Window 关闭代码和相同的最小化
并设置 Window样式=none
我遇到了一个类似的问题,试图让我的应用程序对 Windows 10 触摸键盘的存在做出正确的反应,但它不会这样做,除非 WindowStyle
被设置为其他东西比 None
.
挣扎了一段时间,直到我决定自己尝试设置 Window 的样式并手动删除边框,这让我发现了 WindowChrome
class。
WindowChrome documentation提到了关于WindowStyle="None"
的这个:
One way to customize the appearance of a WPF application window is to set the Window.WindowStyle property to None. This removes the non-client frame from the window and leaves only the client area, to which you can apply a custom style. However, when the non-client frame is removed, you also lose the system features and behaviors that it provides, such as caption buttons and window resizing. Another side effect is that the window will cover the Windows taskbar when it is maximized. Setting WindowStyle.None enables you to create a completely custom application, but also requires that you implement custom logic in your application to emulate standard window behavior.
看来是因为缺少 non-client(或 OS)框架,导致应用程序无法对键盘的存在做出反应。
解决方案是实现自定义 WindowChrome
。可以这样做:
<Window x:Class="WpfApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:shell="clr-namespace:System.Windows.Shell;assembly=PresentationFramework"
Title="MainWindow" Height="350" Width="525" WindowState="Maximized">
<shell:WindowChrome.WindowChrome>
<shell:WindowChrome NonClientFrameEdges="None"
UseAeroCaptionButtons="False"
CornerRadius="0"
GlassFrameThickness="0"
ResizeBorderThickness="0"
CaptionHeight="0" />
</shell:WindowChrome.WindowChrome>
<Grid Background="DarkOrange">
<TextBlock Text="TEST" VerticalAlignment="Center"
HorizontalAlignment="Center" FontSize="32" />
</Grid>
</Window>
如果您绝对必须使用 WindowStyle="None"
,那么根据上面的文档,Window 逻辑必须是自定义的。幸运的是,Microsoft 提供了一个很好的示例,说明如何编写自定义逻辑以对触摸键盘的存在做出反应:See this link.
如果您想将自己的自定义按钮添加到标题栏,请查看 this excellent post 关于样式化您的 Window。
希望对您有所帮助!
更新:
经过进一步调查,发现此解决方案仅适用于 Windows 10 版本 1903。当我们在生产中使用的 1809 上尝试时,它没有用。原因显然是微软已经改变了应用程序在 full-screen 模式下对触摸键盘的反应方式。
这可以通过在 Windows 的两个版本中最大化 Explorer 来轻松测试,并查看在 1809 年如何没有发生任何事情,但在 1903 年 Window 被调整大小以适应剩余的 [=62] =] 在屏幕上。
我注意到的另一件重要事情是,当我从 Visual Studio 启动应用程序时(无论是否连接调试器),当触摸屏出现时,UI 没有反应它, 但是 当我 运行 来自资源管理器的可执行文件时,它确实可以工作。所以在我的测试中,我总是会构建,然后转到 bin\Debug,然后从那里启动 exe。