滚动时限制按钮点击事件

问题描述 投票:0回答:1

我有一个自定义列表类型控件(不是从 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.
winui-3
1个回答
0
投票

让我向您展示一个没有操作事件的示例。至少可以与我笔记本电脑上的触摸显示器配合使用。

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.");
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.