【问题标题】:Scroll grid with buttons- how to prevent button elements from firing while scrolling使用按钮滚动网格 - 如何防止按钮元素在滚动时触发
【发布时间】:2017-04-15 22:30:02
【问题描述】:

我在 wpf 中有一个应用程序,它使用带有 mvvm 模式的 caliburn 微框架,它在带有触摸屏的信息亭中运行。我想滚动按钮以及当用户想要单击它们时。我在滚动查看器中使网格可滚动,但问题是当我离开触摸时,它会引发按钮单击事件。 这是代码(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>

这是关于事件的背后代码

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;
    }
}

滚动是goog,但是当我离开手指的按钮时,这会使重定向

根据以下答案更新代码

【问题讨论】:

  • 好的,编辑完成,如果有效,请告诉我
  • 我刚刚明白你的意思......(尝试在我的回答中将时间更改为 0.5 秒)如果你设置一个断点,你可以看到为你的小卷轴计算的日期时间

标签: c# wpf button scroll grid


【解决方案1】:

您可以针对这个问题实施各种解决方案,

在这里查看我的回答,或者作者回答两种不同的方法,

WPF Click Button Scrollviewer

解决方法是用鼠标左键点击,但可以适应触摸,

我的方法是使用 DateTime,来计算你按下了多少时间,如果你只是触摸一个按钮,那么触摸不到 1 秒,如果你滚动它会超过 1 秒,所以它不会'不引发按钮点击事件

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;

    }

更新

第二个解决方案,去我上面贴的答案,用第二个答案的c#代码,更健壮

【讨论】:

  • 这是一个非常有效的解决方案,但现在的问题在于小卷轴。在小滚动中,按钮事件仍在引发。我修改了这样的代码: if (difference.TotalMilliseconds>500) { e.Handled = true;我用 mouseleftbutton 事件改变了触摸事件
  • @user1654278,所以现在小卷轴仍然会引发按钮事件?
  • 我认为您应该尝试其他解决方案,我认为它对您更有效,我现在将发布代码
  • 是的,我做了 500 毫秒。所以解决方案是在可接受的时间进行测试
  • @user1654278,在玩太多我的答案之前尝试使用 InvokeProvider 的第二个,我实际上更喜欢它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多