WP8中 ListBox x下拉刷新 以及 ScrollViewer/ListBox 的ManipulationCompleted 失效的解决方案
2013-01-06 06:58 F-sea 阅读(2353) 评论(10) 编辑 收藏 举报
今天在做 Wp8 中的ListBox 下拉刷新 发现一个蛋疼的问题 ManipulationCompleted 失效 这个事件死活不会触发 。。。
没有 MainpulationComplated 手势探测就很蛋疼了 (别告诉我用gestures的toolkit 那样做就恶心了。。。。 )
折腾了半天 发现 在ScrollViewer下的Border handler 了MainpulationCompleted 事件 (不知道这个是不是 控件的bug 。。。 囧)
那么既然 ScrollViewer 中拿不到事件 那我就再他下面去取事件吧 。。
直接上代码。。 具体的解释 在代码里面, 具体的说明自己看注释把。。。
public class ScrollBehavior :Behavior<ListBox> { public event EventHandler<ScrollEventArgs> OnScroll; private ScrollContentPresenter _scrollContentPresenter; private ScrollViewer _scrollViewer; protected override void OnAttached() { base.OnAttached(); this.AssociatedObject.LayoutUpdated += (sender, e) => { if (_scrollContentPresenter == null) {
// 获取ListBox 中的 ListBox中的 ScrollViewer 以便获取当前滚动位置 _scrollViewer = FindChildOfType<ScrollViewer>(this.AssociatedObject, obj => { return true; }); if (_scrollViewer == null) { return; }
//获取ScrollViewer 中的ContentPresenter 用来订阅ManipulationCompleted 事件,之所以不取Handle住事件Border 是考虑到 ScrollView 有可能被定制 里面就可能不止一个 Border
//而ContentPresenter 是在border 下面的 事件可以正常捕获 而且 在ScrollViwer 中 ContentPresenter 是唯一的。
_scrollContentPresenter = FindChildOfType<ScrollContentPresenter>(_scrollViewer, obj => { return true; }); if (_scrollContentPresenter != null) { Logger.LogMessage("Event handler attched");
// 订阅事件 获取手势结束时的坐标 _scrollContentPresenter.ManipulationCompleted += OnManipulationCompleted;
// 订阅事件 获取手势开始时的坐标
// 注意:这里之所以不订阅 MainpulationStart事件 是因为 该事件给出的坐标是在点击位置 所在控件中的相对坐标
// 比如手势开始时点击位置是在ListBox 中 第三个ITem 中的一个图片上 那么给出坐标是这个图片中的相对坐标而非ScrollViewer的
// 而 ManipulationCopleted 给出的坐标是ScrollViewer的相对坐标 。。 坐标系不统一很蛋疼的。 _scrollContentPresenter.MouseLeftButtonDown += OnMouseLeftButtonDown; } } }; base.OnAttached(); } System.Windows.Input.MouseButtonEventArgs _buttonDownArgs; void OnMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) { _buttonDownArgs = e; } void OnManipulationCompleted(object sender, System.Windows.Input.ManipulationCompletedEventArgs e) { double delta = e.ManipulationOrigin.Y - _buttonDownArgs.GetPosition(e.ManipulationContainer).Y;/这就是通过MouseLeftButtonDown 获取到坐标的好处,直接统一了坐标系:)
//下面就就是判断手势位置什么的了 我就不解释。。。 ScrollEventArgs 这些我自己定义的参数类 大家就不要在意啦。。。 if ( _scrollViewer.ScrollableHeight == _scrollViewer.ScrollableHeight && delta <-100) { FireOnScroll(new ScrollEventArgs(ScrollState.Bottom)); } else if (_scrollViewer.VerticalOffset ==0 && delta > 100) { FireOnScroll(new ScrollEventArgs(ScrollState.Top)); } } void FireOnScroll(ScrollEventArgs args) { if (OnScroll != null) { OnScroll(_scrollViewer, args); } } static T FindChildOfType<T>(DependencyObject root, Func<T, bool> verifyFunc) where T : class { var queue = new Queue<DependencyObject>(); queue.Enqueue(root); while (queue.Count > 0) { DependencyObject current = queue.Dequeue(); for (int i = VisualTreeHelper.GetChildrenCount(current) - 1; 0 <= i; i--) { var child = VisualTreeHelper.GetChild(current, i); var typedChild = child as T; if (typedChild != null) { if (verifyFunc(typedChild)) return typedChild; } queue.Enqueue(child); } } return null; } }
Windows Phone Developer Network
http://www.wpdevn.com
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!