Scroll grid with buttons- how to prevent button elements from firing while scrolling

﹥>﹥吖頭↗ 提交于 2021-01-28 07:54:38

问题


I have an app in wpf using caliburn micro framework with mvvm pattern which is running in kiosk with touch screen. i want to scroll buttons and when the user wants to click them. I have made grid scrollable inside a scroll viewer but the proplem is that when I leave the touch, it's raising the button-click event. Here's the code (xaml) :

<ScrollViewer VerticalScrollBarVisibility="Hidden"  x:Name="scroller">
    <Grid  ScrollViewer.CanContentScroll="True">

        <Grid.RowDefinitions>
            <RowDefinition Height="15"/>
            <RowDefinition x:Name="Row1"/>
            <RowDefinition Height="15"/>
            <RowDefinition x:Name="Row2"/>
            <RowDefinition Height="15"/>
            <RowDefinition x:Name="Row3"/>
            <RowDefinition Height="15"/>
            <RowDefinition x:Name="Row4"/>
            <RowDefinition Height="15"/>
            <RowDefinition x:Name="Row5"/>
            <RowDefinition Height="15"/>
            <RowDefinition x:Name="Row6"/>
            <RowDefinition Height="15"/>
            <RowDefinition x:Name="Row7"/>
            <RowDefinition Height="15"/>
            <RowDefinition x:Name="Row8"/>
        </Grid.RowDefinitions>

        <Button x:Name="ViewRedirect1" Grid.Row="1">
            <Image Source="{Binding Path=LeftImage1}" Stretch="UniformToFill"/>
        </Button>
        <Button x:Name="ViewRedirect2" Grid.Row="3">
            <Image Source="{Binding Path=LeftImage2}" Stretch="UniformToFill"/>
        </Button>
        <Button x:Name="ViewRedirect3" Grid.Row="5">
            <Image Source="{Binding Path=LeftImage3}" Stretch="UniformToFill"/>
        </Button>
        <Button x:Name="ViewRedirect4" Grid.Row="7">
            <Image Source="{Binding Path=LeftImage4}" Stretch="UniformToFill"/>
        </Button>
        <Button x:Name="ViewRedirect5" Grid.Row="9">
            <Image Source="{Binding Path=LeftImage5}" Stretch="UniformToFill"/>
        </Button>
        <Button x:Name="ViewRedirect6" Grid.Row="11">
            <Image Source="{Binding Path=LeftImage6}" Stretch="UniformToFill"/>
        </Button>
        <Button x:Name="ViewRedirect7" Grid.Row="13">
            <Image Source="{Binding Path=LeftImage7}" Stretch="UniformToFill"/>
        </Button>
        <Button x:Name="ViewRedirect8" Grid.Row="15">
            <Image Source="{Binding Path=LeftImage8}" Stretch="UniformToFill"/>
        </Button>

    </Grid>
</ScrollViewer>

and here is the behind code about the events

private Point scrollStartPoint;

private Point scrollStartOffset;
private DateTime mouseTimer;
private void Scroller_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    mouseTimer = DateTime.Now;

    ScrollViewer scrollViewer = sender as ScrollViewer;
    if (scrollViewer.IsMouseOver)
    {
        scrollStartPoint = e.GetPosition(scrollViewer);
        scrollStartOffset.X = scrollViewer.HorizontalOffset;
        scrollStartOffset.Y = scrollViewer.VerticalOffset;
    }

}

private void Scroller_PreviewMouseMove(object sender, MouseEventArgs e)
{
    ScrollViewer scrollViewer = sender as ScrollViewer;

        if (scrollViewer.IsMouseOver)
        {
            Point currentPoint = e.GetPosition(scrollViewer);

            Point delta = new Point(scrollStartPoint.X - currentPoint.X,
                scrollStartPoint.Y - currentPoint.Y);

            scrollTarget.X = scrollStartOffset.X + delta.X;
            scrollTarget.Y = scrollStartOffset.Y + delta.Y;

            scrollViewer.ScrollToHorizontalOffset(scrollTarget.X);
            scrollViewer.ScrollToVerticalOffset(scrollTarget.Y);

        }
}

private void Scroller_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
    ScrollViewer scrollViewer = sender as ScrollViewer;
    if (scrollViewer.IsMouseCaptured) { 
        scrollViewer.ReleaseMouseCapture();
    }
    TimeSpan difference = DateTime.Now - mouseTimer;
    if (difference.TotalMilliseconds>500)
    {
        e.Handled = true;
    }
}

the scroll is goog but when in the button that I leave the finger up, this makes the redirecting

updated code based on answer below


回答1:


You can implement various solutions for this problem,

Look at my answer here, or the authors answer for two separate ways to do it,

WPF Click Button Scrollviewer

The solution is with a left mouse click button, but can be adapted for touch,

my way was to use DateTime, to calculate how much time you press, if you are just touching a button, then it would be less than 1second touch, if you are scrolling it would be more than 1 second, so it doesn't raise the button click event

private DateTime mouseTimer;

private void Scroller_PreviewTouchDown(object sender, TouchEventArgs e)
    {
        mouseTimer = DateTime.Now;
        ScrollViewer scrollViewer = sender as ScrollViewer;
        if (scrollViewer.IsMouseOver)
        {
            scrollStartPoint = e.GetTouchPoint(scrollViewer).Position; 
            scrollStartOffset.X = scrollViewer.HorizontalOffset;
            scrollStartOffset.Y = scrollViewer.VerticalOffset;
        }

    }
private void Scroller_PreviewTouchUp(object sender, TouchEventArgs e)
    {

        ScrollViewer scrollViewer = sender as ScrollViewer;
        if(scrollViewer.IsMouseCaptured)
        {
            scrollViewer.ReleaseAllTouchCaptures();
        }

        TimeSpan difference = DateTime.Now - mouseTimer;

              if (difference.TotalSeconds < 1)
               {
                btn_Click(sender, e); //button you want or don't want to rise event
               }
              else
              return;

    }

UPDATE

Second solution, go to the answer I posted above and use the c# code in the second answer, it is more robust



来源:https://stackoverflow.com/questions/40908038/scroll-grid-with-buttons-how-to-prevent-button-elements-from-firing-while-scrol

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!