我有一个自定义列表类型控件(不是从 ListView 派生的),具有 DataTemplate 支持和各种交互功能。为了管理滚动视图的滚动,我处理了滚动视图内容的操作模式。如果用户在模板内加载按钮并在滚动时与其交互,则列表会滚动,但按钮的单击事件也会在触摸释放时触发。 如果我不处理操作,则不会触发按钮单击。
注意:我无权访问源中的这些按钮
<ScrollViewer>
<StackPanel x:Name="stack">
<Grid Height="100">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button Grid.Column="0">Click here</Button>
<Border Background="AntiqueWhite" Grid.Column="1"/>
</Grid>
<Grid Height="100">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button Grid.Column="0">Click here</Button>
<Border Background="Aqua" Grid.Column="1"/>
</Grid>
<Grid Height="100">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button Grid.Column="0">Click here</Button>
<Border Background="AntiqueWhite" Grid.Column="1"/>
</Grid>
...
...
....
<Grid Height="100">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button Grid.Column="0">Click here</Button>
<Border Background="AntiqueWhite" Grid.Column="1"/>
</Grid>
<Grid Height="100">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button Grid.Column="0">Click here</Button>
<Border Background="Aqua" Grid.Column="1"/>
</Grid>
</Grid>
</StackPanel>
public sealed partial class MainWindow : Window
{
private double previousOffset;
public MainWindow()
{
this.InitializeComponent();
this.stack.ManipulationMode = ManipulationModes.All;
this.stack.ManipulationDelta += this.Content_ManipulationDelta;
this.stack.ManipulationStarting += this.Content_ManipulationStarting;
}
private void Content_ManipulationStarting(object sender, ManipulationStartingRoutedEventArgs e)
{
this.previousOffset = this.scrollview.VerticalOffset;
}
private void Content_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
if (e.PointerDeviceType == Microsoft.UI.Input.PointerDeviceType.Mouse)
{
return;
}
this.scrollview.ScrollToVerticalOffset(this.previousOffset - e.Cumulative.Translation.Y);
}
bool changed;
private void Button_Click(object sender, RoutedEventArgs e)
{
if (changed)
text.Background = new SolidColorBrush(Colors.Red);
else
text.Background = new SolidColorBrush(Colors.Green);
changed = !changed;
}
}
I have tried the below things to achieve this, but none worked.
- Tried Setting Manipulation mode to system and do my customization on interaction feature using AddHandler for Manipulation event, none of the event triggered.
- Handled Pointer Presses event in Scrollview's content.
- Tried Capturing pointer in Pressed, released and moved.
- IsTapEnabled to false.
- e.handled as false in Manipulation delta with Manipulation Mode: All.
- CancelDirectManipulation for Textblock in pointer pressed.
- Suggested to user - Workaround with scroll check in button click, but not happy with suggestion.
让我向您展示一个没有操作事件的示例。至少可以与我笔记本电脑上的触摸显示器配合使用。
Shell.xaml
<Page
x:Class="WinUIApp2.Shell"
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:local="using:WinUIApp2"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
mc:Ignorable="d">
<Page.Resources>
<DataTemplate
x:Key="ButtonItemTemplate"
x:DataType="x:String">
<Button
Click="Button_Click"
Content="{x:Bind}" />
</DataTemplate>
</Page.Resources>
<ScrollViewer>
<ItemsControl
ItemTemplate="{StaticResource ButtonItemTemplate}"
ItemsSource="{x:Bind Items}" />
</ScrollViewer>
</Page>
Shell.xaml.cs
using Microsoft.UI.Xaml.Controls;
using System.Collections.ObjectModel;
namespace WinUIApp2;
public sealed partial class Shell : Page
{
public Shell()
{
InitializeComponent();
for (int i = 0; i < 100; i++)
{
Items.Add($"Item {i}");
}
}
public ObservableCollection<string> Items { get; } = [];
private void Button_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (sender is not Button button)
{
return;
}
System.Diagnostics.Debug.WriteLine($"{button.Content} clicked.");
}
}