我正在为支持触控的设备开发WPF。我面临一个奇怪的问题。我的XAML结构是
<ScrollViewer>
<StackPanel orientation="Horizontal">
<!-- Control goes here -->
</StackPanel>
<ScrollViewer>
现在
问题是我必须同时拥有这两个功能。
是否有任何解决方法,以便滚动查看器滚动,并且 actionscompleted 事件也会触发。
请帮忙。
答案 0 :(得分:1)
我有同样的问题。你至少有两个选择
我选择了第二个。只需创建一个自定义控件,继承自ScrollViewer,在Generic.xaml中,您只需要输入<ContentPresenter />
,仅此而已。
真正的工作是在代码背后,但也没有那么复杂。我必须检查用户是否触摸了按钮或只是想滚动。诀窍是检查触摸点上的内容并打开/关闭平移模式。
以下是代码:
namespace Demo.Controls
{
public class ScrollViewerWithTouch : ScrollViewer
{
private PanningMode panningMode;
private bool panningModeSet;
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;
}
}
}