我有一个ListView
来展示购物车里的商品。 datatemplate
定义了每个产品的增加和减少数量按钮。
如果用户想点击其中一个按钮,有可能会误触按钮旁边,导致触发ItemClick
事件。我想在按钮区域禁用ItemClick
。 我考虑获取ItemClick
事件发生的位置,并确定它是否在我定义的禁用区域中。
这可行吗?还有其他想法吗?
我有一个ListView
来展示购物车里的商品。 datatemplate
定义了每个产品的增加和减少数量按钮。
如果用户想点击其中一个按钮,有可能会误触按钮旁边,导致触发ItemClick
事件。我想在按钮区域禁用ItemClick
。 我考虑获取ItemClick
事件发生的位置,并确定它是否在我定义的禁用区域中。
这可行吗?还有其他想法吗?
ItemClick
处理程序中,写上 if (e.OriginalSource == **作为禁用区域的元素**) return;
。ItemClickedEventArgs
是一个 RoutedEventArgs
,它总是包含其来源的元素。请参阅https://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.controls.itemclickeventargs。为什么要走弯路?
您可以通过更改DataTemplate
的方式,使每个ListViewItem
分为两个部分:"更改金额部分"和"物品信息部分":
<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>
第一种解决方案:您可以找出引发事件的OriginalSource是什么。如果它是“更改金额部分”,那么用户可能误触了它,事件应该被取消;如果是“项目信息部分”,则应该触发该事件:
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
,对于按钮添加 OnIncreaseTapped
和 OnDecreaseTapped
):
<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
来消除这个区域,就像这样:
而不是这样:
建议1
您可以监听 DataTemplate
的 ManipulationStarted
根 ,并且在事件处理程序中检查 e.Position
是否靠近按钮。如果太靠近,则将 bool
设置为 IsCloseToStepperButtons
并在 ItemClick
事件处理程序中检查该布尔值。
尚未测试,但我认为事件按所需顺序触发。
建议2
您可以跳过整个 ItemClick
事件,并向 DataTemplate
的其他部分添加事件侦听器。 在两个部分之间放置边距以防止意外点击。