gpt4 book ai didi

c# - WPF,ScrollViewer 在长按之前消耗触摸

转载 作者:行者123 更新时间:2023-11-30 20:53:35 25 4
gpt4 key购买 nike

我对这个 WPF 世界有点陌生。而且我有点困惑为什么我的 ScrollView 正在消耗我的触摸事件。

我现在的情况是这样的:

我有一个带有 ItemsControl 的 ScrollViewer。在此 ItemsControl 中,我使用 Wrappanel 来显示多个矩形。我的 ScrollViewer 应该可以垂直滚动以显示向下包裹的矩形。在这些矩形中的每一个上,我都使用各种处理程序创建了 CustomBehaviour。其中一个处理程序是一种“创造性”的方式来处理 LongPressGestures。

问题如下,在行为检测到我的长按之前,我的 ScrollViewer 正在其 PreviewTouchMove 处理程序中捕获我的 TouchDevice。

如何防止我的 ScrollViewer 过早捕获我的 TouchDevice?如何确保我可以滚动我的 ScrollViewer 并执行我的 LongPress、DoubleClick(仍然有效)、SingleClick(仍然有效)以及我可能添加到此自定义行为的其他手势?

我在 stackoverflow 和 google 上发现了类似的问题,只是我没有弄清楚我的具体情况。

Something with a CustomThumb <-- 此链接通过制作 CustomThumb 解决了问题。我可以以某种方式将其重新用于我的行为吗?通过在我的行为处理程序中尽早捕获 TouchDevice?

如果一切都失败了。除了这种 ScrollViewer 和 CustomBehaviour 组合之外,还有其他选择吗?


编辑:

与此同时。我重试了 CustomThumb 方法。我现在从我的 CustomBehaviour 得到了长按,而 UIElements(具有该行为)位于 ScrollViewer 上。但是 ScrollViewer 的滚动功能仍然不起作用。我添加的赏金也将奖励给帮助我让它再次正常工作的人(因为答案应该与这个 CustomThumb 解决方案的方向相同)。

最佳答案

我之前遇到过类似的问题。我无法同时使用滚动、触摸和样式。最后我开发了一个自定义的 ScrollViewer。它比您想象的要容易,因为您只需要观察/更改一些基本方法。

在您的情况下,您可以检查用户按下的是空表面还是列表项。如果它是一个列表项,你需要检查它是短按(因此,touchup 也发生在 touchdown 之后)还是长按。

可以使用 PanningMode 配置滚动。它允许您用手指在整个用户控件上滚动。

这是我的滚动查看器版本。当用户按下按钮并随后打开时,它会关闭滚动模式。

public class ScrollViewerWithTouch : ScrollViewer   
{
/// <summary>
/// Original panning mode.
/// </summary>
private PanningMode panningMode;

/// <summary>
/// Set panning mode only once.
/// </summary>
private bool panningModeSet;

/// <summary>
/// Initializes static members of the <see cref="ScrollViewerWithTouch"/> class.
/// </summary>
static ScrollViewerWithTouch()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ScrollViewerWithTouch), new FrameworkPropertyMetadata(typeof(ScrollViewerWithTouch)));
}

protected override void OnManipulationCompleted(ManipulationCompletedEventArgs e)
{
base.OnManipulationCompleted(e);

// set it back
this.PanningMode = this.panningMode;
}

protected override void OnManipulationStarted(ManipulationStartedEventArgs e)
{
// figure out what has the user touched
var result = VisualTreeHelper.HitTest(this, e.ManipulationOrigin);
if (result != null && result.VisualHit != null)
{
var hasButtonParent = this.HasButtonParent(result.VisualHit);

// if user touched a button then turn off panning mode, let style bubble down, in other case let it scroll
this.PanningMode = hasButtonParent ? PanningMode.None : this.panningMode;
}

base.OnManipulationStarted(e);
}

protected override void OnTouchDown(TouchEventArgs e)
{
// store panning mode or set it back to it's original state. OnManipulationCompleted does not do it every time, so we need to set it once more.
if (this.panningModeSet == false)
{
this.panningMode = this.PanningMode;
this.panningModeSet = true;
}
else
{
this.PanningMode = this.panningMode;
}

base.OnTouchDown(e);
}

private bool HasButtonParent(DependencyObject obj)
{
var parent = VisualTreeHelper.GetParent(obj);

if ((parent != null) && (parent is ButtonBase) == false)
{
return HasButtonParent(parent);
}

return parent != null;
}
}

关于c# - WPF,ScrollViewer 在长按之前消耗触摸,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19855920/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com