WP8中 ListBox x下拉刷新 以及 ScrollViewer/ListBox 的ManipulationCompleted 失效的解決方案


 

今天在做 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; } }

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM