关于触摸屏下使用触摸键盘向文本框输入文本后,点击按钮弹出窗口时,窗口渲染内容不正常的问题

james lee 0 信誉分
2024-05-14T08:19:58.9133333+00:00

在之前的项目中发现了这样的一个问题:

在一个全屏显示的软件中,使用触摸屏操作,触摸文本框(TextBox)弹出触摸键盘,输入任意文本内容后,在不关闭触摸键盘的情况下,点击一个按钮(Button),弹出一个窗口(Window),有时候这个窗口的显示是正常的,而有时候是不正常的(当显示不正常是无法弹出窗口,通过shift+tab或从任务栏中能发现窗口其实已创建,但无法正确加载,可能只能加载部分内容,其中的按钮控件可以交互但不一定可见)

该问题困扰了我很长一段时间,直到最近在提示窗口(Window)中新增了AllowsTransparency="True"后,问题被解决了。但我仍不清楚这是什么原因。

以下是测试项目代码,当提示窗口xaml中的

AllowsTransparency="True"

被移除后,将会出现上文描述中的问题

主窗口xaml:

<Window x:Class="CusMsgWinTestDemoWithoutDev.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:CusMsgWinTestDemoWithoutDev"
        mc:Ignorable="d"
        Title="MainWindow"
        Width="1920" 
        Height="1080"
        WindowState="Maximized"
        WindowStyle="None">
    <Window.Resources>
        <ResourceDictionary>
            <Style TargetType="TextBlock">
                <Setter Property="HorizontalAlignment" Value="Left"/>
                <Setter Property="VerticalAlignment" Value="Center"/>
                <Setter Property="FontFamily" Value="Microsoft YaHei UI"/>
                <Setter Property="FontSize" Value="25"/>
                <Setter Property="FontWeight" Value="Bold"/>
                <Setter Property="Margin" Value="10,5"/>
                <Style.Triggers>
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter Property="Opacity" Value="0.5"/>
                    </Trigger>
                </Style.Triggers>
            </Style>

            <Style x:Key="LocalControl" TargetType="{x:Type Control}">
                <Setter Property="Height" Value="100"/>
                <Setter Property="Width" Value="1000"/>
                <Setter Property="Margin" Value="10"/>
            </Style>

            <Style TargetType="TextBox" BasedOn="{StaticResource LocalControl}">
                <Setter Property="Background" Value="White"/>
                <Setter Property="BorderBrush" Value="#FF8F8BDE"/>
                <Setter Property="BorderThickness" Value="1"/>
                <Setter Property="Foreground" Value="#FF666666"/>
                <Setter Property="FontSize" Value="30"/>
                <Setter Property="SelectionBrush" Value="#FF8F8BDE"/>
                <Setter Property="HorizontalContentAlignment" Value="Center"/>
                <Setter Property="CaretBrush" Value="#FF8F8BDE"/>
                <Style.Triggers>
                    <Trigger Property="IsReadOnly" Value="True">
                        <Setter Property="Background" Value="#FFEFF2FB"/>
                        <Setter Property="BorderBrush" Value="#FFCCCCCC"/>
                    </Trigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsReadOnly" Value="False"/>
                            <Condition Property="IsKeyboardFocusWithin" Value="True"/>
                        </MultiTrigger.Conditions>
                        <Setter Property="Background" Value="LightYellow"/>
                    </MultiTrigger>
                </Style.Triggers>
            </Style>

            <Style TargetType="{x:Type Button}" BasedOn="{StaticResource LocalControl}">
                <Setter Property="FontSize" Value="30"/>
                <Setter Property="FontWeight" Value="Bold"/>
                <Setter Property="BorderBrush" Value="Transparent"/>
                <Setter Property="BorderThickness" Value="0"/>
                <Setter Property="Background" Value="#FF6969F9"/>
                <Setter Property="Foreground" Value="White"/>
                <Setter Property="FontFamily" Value="Microsoft YaHei UI"/>
                <Setter Property="Cursor" Value="Hand"/>
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="#FE6969F9"/>
                    </Trigger>
                    <Trigger Property="IsPressed" Value="True">
                        <Setter Property="Opacity" Value="0.8"/>
                    </Trigger>
                </Style.Triggers>
            </Style>

            <Style x:Key="SimpleButtonCancelBtnStyle" TargetType="{x:Type Button}">
                <Setter Property="Width" Value="{Binding ActualHeight, Mode=OneWay, RelativeSource={RelativeSource Self}}"/>
                <Setter Property="Background" Value="Transparent"/>
                <Setter Property="BorderBrush" Value="Transparent"/>
                <Setter Property="BorderThickness" Value="0"/>
                <Setter Property="Cursor" Value="Hand"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate>
                            <Border Background="{TemplateBinding Background}" 
                            BorderBrush="{TemplateBinding BorderBrush}" 
                            BorderThickness="{TemplateBinding BorderThickness}">
                                <Viewbox Margin="5">
                                    <Path Height="32" Width="32" Fill="#FFD02127" HorizontalAlignment="Center" VerticalAlignment="Center">
                                        <Path.Data>
                                            <PathGeometry Figures="M18.8,16l8.9-8.9c0.4-0.4,0.4-1,0-1.4l-1.4-1.4c-0.4-0.4-1-0.4-1.4,0L16,13.2L7.1,4.3c-0.4-0.4-1-0.4-1.4,0
L4.3,5.7c-0.4,0.4-0.4,1,0,1.4l8.9,8.9l-8.9,8.9c-0.4,0.4-0.4,1,0,1.4l1.4,1.4c0.4,0.4,1,0.4,1.4,0l8.9-8.9l8.9,8.9
c0.4,0.4,1,0.4,1.4,0l1.4-1.4c0.4-0.4,0.4-1,0-1.4L18.8,16z">
                                            </PathGeometry>
                                        </Path.Data>
                                    </Path>
                                </Viewbox>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="#00000000"/>
                    </Trigger>
                    <Trigger Property="IsMouseOver" Value="False">
                        <Setter Property="Background" Value="Transparent"/>
                    </Trigger>
                    <Trigger Property="IsPressed" Value="True">
                        <Setter Property="Opacity" Value="0.8"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="100"/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <Grid Grid.Row="0" Background="#FF8F8BDE">
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <TextBlock Foreground="White" Text="MainWindow"/>
            <Button Grid.Column="1" Style="{StaticResource SimpleButtonCancelBtnStyle}" Click="Btn_Cancel_Click"/>
        </Grid>

        <StackPanel Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center">
            <TextBox Margin="10" Text="Touch here to show touch keyboard and input anything"/>
            <Viewbox Margin="10" Height="60">
                <CheckBox x:Name="CheckBox_ActivatedSetTopmost" Content="Activated Set Topmost"/>
            </Viewbox>
            <Button Margin="10" Content="Touch here to show CustomMessageWindow after inputting" Click="Btn_Show_Click"/>

        </StackPanel>

    </Grid>
</Window>

主窗口cs:

using System.Windows;
namespace CusMsgWinTestDemoWithoutDev
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        private void Btn_Cancel_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }
        private void Btn_Show_Click(object sender, RoutedEventArgs e)
        {
            CustomMessageWindow customMessageWindow = new CustomMessageWindow()
            {
                Owner = this,
                ActivatedSetTopmost = this.CheckBox_ActivatedSetTopmost.IsChecked == true,
            };
            //Activate();
            customMessageWindow.ShowDialog();
        }
    }
}

提示窗口xaml:

<Window x:Class="CusMsgWinTestDemoWithoutDev.CustomMessageWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:CusMsgWinTestDemoWithoutDev"
        mc:Ignorable="d"
        Title="CustomMessageWindow"
        MinHeight="360"
        MinWidth="660"
        AllowsTransparency="True"
        SizeToContent="WidthAndHeight"
        WindowStyle="None"
        WindowStartupLocation="CenterScreen" 
        ResizeMode="NoResize"
        BorderThickness="1"
        BorderBrush="#FF8F8BDE"
        Background="#FFEFF2FB"
        Activated="window_Activated" 
        Deactivated="window_Deactivated">
    <Window.Resources>
        <ResourceDictionary>
            <Style TargetType="TextBlock">
                <Setter Property="HorizontalAlignment" Value="Left"/>
                <Setter Property="VerticalAlignment" Value="Center"/>
                <Setter Property="FontFamily" Value="Microsoft YaHei UI"/>
                <Setter Property="FontSize" Value="25"/>
                <Setter Property="FontWeight" Value="Bold"/>
                <Setter Property="Margin" Value="10,5"/>
                <Style.Triggers>
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter Property="Opacity" Value="0.5"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
            <Style x:Key="SimpleButtonCancelBtnStyle" TargetType="{x:Type Button}">
                <Setter Property="Width" Value="{Binding ActualHeight, Mode=OneWay, RelativeSource={RelativeSource Self}}"/>
                <Setter Property="Background" Value="Transparent"/>
                <Setter Property="BorderBrush" Value="Transparent"/>
                <Setter Property="BorderThickness" Value="0"/>
                <Setter Property="Cursor" Value="Hand"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate>
                            <Border Background="{TemplateBinding Background}" 
                            BorderBrush="{TemplateBinding BorderBrush}" 
                            BorderThickness="{TemplateBinding BorderThickness}">
                                <Viewbox Margin="5">
                                    <Path Height="32" Width="32" Fill="#FFD02127" HorizontalAlignment="Center" VerticalAlignment="Center">
                                        <Path.Data>
                                            <PathGeometry Figures="M18.8,16l8.9-8.9c0.4-0.4,0.4-1,0-1.4l-1.4-1.4c-0.4-0.4-1-0.4-1.4,0L16,13.2L7.1,4.3c-0.4-0.4-1-0.4-1.4,0
L4.3,5.7c-0.4,0.4-0.4,1,0,1.4l8.9,8.9l-8.9,8.9c-0.4,0.4-0.4,1,0,1.4l1.4,1.4c0.4,0.4,1,0.4,1.4,0l8.9-8.9l8.9,8.9
c0.4,0.4,1,0.4,1.4,0l1.4-1.4c0.4-0.4,0.4-1,0-1.4L18.8,16z">
                                            </PathGeometry>
                                        </Path.Data>
                                    </Path>
                                </Viewbox>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="#00000000"/>
                    </Trigger>
                    <Trigger Property="IsMouseOver" Value="False">
                        <Setter Property="Background" Value="Transparent"/>
                    </Trigger>
                    <Trigger Property="IsPressed" Value="True">
                        <Setter Property="Opacity" Value="0.8"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
            <Style x:Key="SimpleButtonStyle" TargetType="{x:Type Button}">
                <Setter Property="Height" Value="80"/>
                <Setter Property="Width" Value="200"/>
                <Setter Property="Margin" Value="8"/>
                <Setter Property="FontSize" Value="25"/>
                <Setter Property="FontWeight" Value="Bold"/>
                <Setter Property="BorderBrush" Value="Transparent"/>
                <Setter Property="BorderThickness" Value="0"/>
                <Setter Property="Background" Value="#FF6969F9"/>
                <Setter Property="Foreground" Value="White"/>
                <Setter Property="FontFamily" Value="Microsoft YaHei UI"/>
                <Setter Property="Cursor" Value="Hand"/>
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="#FE6969F9"/>
                    </Trigger>
                    <Trigger Property="IsPressed" Value="True">
                        <Setter Property="Opacity" Value="0.8"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="50"/>
            <RowDefinition/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid Grid.Row="0" Background="#FF8F8BDE" MouseLeftButtonDown="Grid_MouseLeftButtonDown">
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <TextBlock Foreground="White" Text="Custom Message Window"/>
            <Button Grid.Column="1" Style="{StaticResource SimpleButtonCancelBtnStyle}" IsCancel="True" Click="Btn_Cancel_Click"/>
        </Grid>
        <Grid Grid.Row="1">
            <TextBlock Foreground="#FF666666" Text="Message" HorizontalAlignment="Center"/>
        </Grid>
        <Grid Grid.Row="2">
            <Button Style="{StaticResource SimpleButtonStyle}" IsDefault="True" Content="Confirm" Click="Btn_Confirm_Click"/>
        </Grid>
    </Grid>
</Window>

提示窗口cs:


using System;
using System.Windows;
using System.Windows.Input;
namespace CusMsgWinTestDemoWithoutDev
{
    /// <summary>
    /// CustomMessageWindow.xaml 的交互逻辑
    /// </summary>
    public partial class CustomMessageWindow : Window
    {
        public bool ActivatedSetTopmost { get; set; } = false;
        public CustomMessageWindow()
        {
            InitializeComponent();
        }
        private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            try
            {
                DragMove();
            }
            catch (Exception)
            {
            }
        }
        private void Btn_Cancel_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = false;
        }
        private void Btn_Confirm_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = true;
        }
        private void window_Activated(object sender, EventArgs e)
        {
            if (ActivatedSetTopmost)
                this.Topmost = true;
            //UpdateLayout();
        }
        private void window_Deactivated(object sender, EventArgs e)
        {
            if (ActivatedSetTopmost)
                this.Topmost = false;
        }
    }
}

Windows
Windows
Microsoft 操作系统系列,可跨个人计算机、平板电脑、笔记本电脑、手机、物联网设备、独立混合现实头戴显示设备、大型协作屏幕和其他设备运行。
158 个问题
.NET
.NET
基于 .NET 软件框架的 Microsoft 技术。
35 个问题
Windows Presentation Foundation
Windows Presentation Foundation
.NET Framework 的一部分,它提供统一的编程模型,用于在 Windows 上构建业务线桌面应用程序。
71 个问题
C#
C#
一种面向对象的类型安全的编程语言,它起源于 C 语言系列,包括对面向组件的编程的支持。
140 个问题
{count} 票