触摸屏上WPF ListViewItem事件无法正确触发

6
 <Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        WindowState="Maximized"
        Title="MainWindow" Height="550" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="4*"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <TextBox Name="TextBox" VerticalContentAlignment="Center" FontSize="30" ></TextBox>
        <ListView Grid.ColumnSpan="6"  Grid.Row="1"
                     x:Name="GridControlProducts"
                    SelectionMode="Single"
                    ScrollViewer.HorizontalScrollBarVisibility="Disabled"
                    ScrollViewer.VerticalScrollBarVisibility="Disabled">
            <ListView.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ListView.ItemsPanel>
            <ListView.ItemContainerStyle>
                <Style TargetType="{x:Type ListViewItem}">
                    <Setter Property="Width" Value="200"/>
                    <Setter Property="Height" Value="200"/>
                    <EventSetter Event="PreviewMouseDown" Handler="button_Click" />
                </Style>
            </ListView.ItemContainerStyle>
        </ListView>       


        <Button Content="Close" Grid.Column="0" Grid.Row="2" Click="Button_Click_1" ></Button>

    </Grid>
</Window>
// code behind
public MainWindow()
        {
            InitializeComponent();

            for (int i = 0; i < 10; i++)
            {
                this.GridControlProducts.Items.Add("Test");
            }
        }

 private int c = 1;
        private void button_Click(object sender, RoutedEventArgs e)
        {
            this.TextBox.Text = this.c++.ToString();
        }

我有一个WPF触摸屏应用程序,其中包含一个产品列表的列表视图模板。
使用鼠标一切正常。然而,在触摸屏上,触摸事件并不总是会触发。例如,如果我在我的列表视图中连续按下10个按钮,可能会有7次触摸被注册,而3次触摸则没有。
如果我单独触摸一个标准按钮,则非常灵敏。但我的模板中的按钮则没有(很容易出现问题)。
我创建了一个简单的测试应用程序(见上文),测试应用程序的行为与我的应用程序相同。
当触摸未被注册时,之前选定的listviewitem仍然被选中,而我选择但未被注册的项目会变成浅蓝色(就像在鼠标悬停时一样)。
如有帮助,将不胜感激。

如果您使用最新版本的Visual Studio 2017和.Net Framework,是否会出现这种情况?在WPF中的Touch方面进行了改进和错误修复。 - Tony
我升级到了针对最新框架4.7.2的VS 2017版本,但是问题依旧存在。在列表视图中,触摸事件只会随机触发。 - Saoirse
我没有触摸屏来测试这个,但如果我正在开发一个新的触摸应用程序,我会使用UWP和它的新API。 - Tony
1
谢谢,但不幸的是触摸屏功能是现有应用程序的新功能。这似乎只是WPF固有的错误。 - Saoirse
3个回答

5
<configuration>
  <runtime>
    <AppContextSwitchOverrides value="Switch.System.Windows.Input.Stylus.DisableStylusAndTouchSupport=true" />
  </runtime>
</configuration>

终于找到了解决方案。我将上述内容放入我的配置文件中,问题得到解决。

感谢所有回复。


看起来可以工作了!鼠标指针也被隐藏了,没有鼠标悬停事件。 - asdf
1
它确实解决了触摸有时无法触发的问题,但由于它完全禁用了触摸,其他功能如缩放、滚动等也不再起作用。有没有人找到这些问题的另一个解决方案? - Luishg

2

摘要

  • 不要在ListView/ListBox中使用Click事件,应改用PreviewMouseDown
  • 你的触摸设备可能比其他设备的触摸精度低。

细节

几年前我也遇到了同样的问题,并发现不同的触摸设备会有不同的表现。在大多数触摸设备上,触摸功能每次都可以正常工作。但在某些设备上,触摸可能会随机丢失。

如果你试着注意一下自己在触摸屏上的动作,你可能会发现,只要手指按下时稍微移动一点距离,触摸就会丢失。这种情况只会发生在ListViewItem或ListBoxItem上,因为ListView和ListBox会处理触摸事件并重新引发它们以实现滚动行为。

MouseDownMouseUp在同一个控件上会产生一个Click事件,触摸事件也是如此。但在ListBox或ListView中,点击事件必须发生在同一个点而不是同一个控件上。因为ListView/ListBox没有必要先处理鼠标事件,所以鼠标点击可以正常工作。

不同种类的触摸设备之间的区别在于它们的触摸精度。触摸精度越低,丢失的触摸事件就越多。

你可以做的是:

  • 不要在ListView/ListBox中使用Click事件,应改用PreviewMouseDown

这绝对是WPF的bug。 - walterlv
我们可以在UWP中使用ItemClick。 - lindexi

0

我知道这个问题已经很老了,但也许还有其他人像我一样在寻找解决方案。walterlv非常清楚地描述了这个问题。如果你不需要ListView的触摸滚动行为,而且你对SelectionChanged事件感兴趣,你可以将以下代码添加到你的ListView中:

<ListView.ItemContainerStyle>
   <Style TargetType="ListViewItem">
      <Style.Triggers>
         <Trigger Property="IsStylusOver" Value="True">
            <Setter Property="IsSelected" Value="True"/>
         </Trigger>
      </Style.Triggers>
   </Style>
</ListView.ItemContainerStyle>

这样,每次触摸ListViewItem都会可靠地选择它并触发SelectionChanged事件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接