ItemClick 事件在 ListView 上的位置 Windows Phone 8.1

Position of ItemClick event on a ListView Windows Phone 8.1

我有一个 ListView 显示购物车中的产品。 datatemplate 为每个产品定义了一个 increment 和一个 decrement 数量按钮。

如果用户想要点击这些按钮之一,他们有可能点击按钮旁边的按钮,因此会触发 ItemClick 事件。我想在按钮区域禁用 ItemClick。我想到了获取 ItemClick 事件发生的位置,并确定它是否在我定义的禁用区域中。

可能吗?还有其他想法吗?

建议 1
如果输入靠近按钮,您可能能够收听 DataTemplateManipulationStarted 根并检查事件处理程序中的 e.Position。如果距离太近,将 bool 设置为 true,例如 IsCloseToStepperButtons 并在 ItemClick 事件处理程序中检查该布尔值。

尚未对此进行测试,但我认为事件已按所需顺序触发。

建议2
您可以跳过整个 ItemClick 事件并将事件侦听器添加到 DataTemplate 的另一部分。在两个部分之间留一个边距以防止意外点击。

有一种简单的方法可以做到这一点。使用一个元素作为这些 increment/decrement 按钮周围的 "disabled area"。在 ItemClick 处理程序中,说 if (e.OriginalSource == **the element which is the disabled area**) return;.

这是可行的,因为 ItemClickedEventArgs 是一个 RoutedEventArgs,它始终包含它的来源元素。参见 https://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.controls.itemclickeventargs

为什么要如此艰难?

您可以更改 DataTemplate,将每个 ListViewItem 分为两部分,"change amount part""item's info part" :

    <ListView ItemClick="OnItemClick">
        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ListViewItem">
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*"/>
                                    <ColumnDefinition Width="100"/>
                                </Grid.ColumnDefinitions>
                                <!-- This is the item's info part -->
                                <StackPanel Orientation="Horizontal" Grid.Column="0" >
                                    <TextBlock Text="{Binding Title}" />
                                    <TextBlock Text="{Binding Qnty}" />
                                </StackPanel>
                                <!-- This is the change amount part -->
                                <StackPanel Tag="Oops!" Orientation="Horizontal" Grid.Column="1" >
                                    <Button Content="▲" />
                                    <Button Content="▼" />
                                </StackPanel>
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ListView.ItemContainerStyle>
    </ListView>

现在您可以尝试以下方法之一来正确处理ItemClick

第一个解决方案: 您可以找出引发 ItemClick 事件的 OriginalSource 是什么。如果是 "change amount part",那么用户可能误点了它,事件应该被取消,如果是 "item's info part" 那么应该引发事件:

    private void OnItemClick(object sender, ItemClickEventArgs e)
    {
        var tag = ((FrameworkElement)e.OriginalSource).Tag;

        if (tag != null && tag.ToString() == "Oops!")
        {
            return;
        }
        //else: do whatever needs to be done on item click
    }

第二种方案: 您可以将 ListView 设置为 SelectionMode="None"IsItemClickEnabled="False",然后我手动为每个元素添加了 Tapped 处理程序(例如,ItemTapped 用于项目的信息部分,OnIncreaseTappedOnDecreaseTapped 按钮):

    <ListView ItemClick="OnItemClick" SelectionMode="None" IsItemClickEnabled="False">
         ...
                                <!-- This is the item's info part -->
                                <StackPanel Orientation="Horizontal" Tapped = "OnItemTapped" Grid.Column="0" >
                                    <TextBlock Text="{Binding Title}" />
                                    <TextBlock Text="{Binding Qnty}" />
                                </StackPanel>
                                <!-- This is the change amount part -->
                                <StackPanel Tag="Oops!" Orientation="Horizontal" Grid.Column="1" >
                                    <Button Content="▲" Tapped = "OnIncreaseTapped"/>
                                    <Button Content="▼" Tapped = "OnDecreaseTapped"/>
                                </StackPanel>
                            </Grid>

第三种解法: 为什么还要让用户点击错误的区域?我宁愿使用这样的 ItemTemplate 来摆脱这个区域:

而不是这个: