2014-05-14 146 views
2

我目前正在捕獲頁面上的PointerMoved事件以便與水平菜單一起使用。所以用戶可以向左/向右滑動,頁面會相應地生成動畫。ListView上的水平滾動

這適用於用戶觸摸靜態元素(TextBlock等),但如果他們觸摸ListView它捕捉觸摸事件。

我該如何實現ListView,因此當用戶垂直滾動時,它可以正常工作,但是當用戶水平滾動時,會將事件傳遞給我的代碼?

回答

5

這是可能的,但你需要一個小竅門。作爲參考,我把這裏放在Rob Caplan's article

讓我們開始:

  1. 第一 - 在那裏是你的事件? - 回答很簡單 - 當你有ScrollViewer啓用時,所有的事件都會被攔截並處理。您ListView將只獲得PointerEntered事件,並且緊隨其後PointerExited,所有進一步的處理都由ScrollViewer處理。那就是問題所在。但正如我所說,有一種方法可以做你想做的事。

  2. 爲此,讓我們假設你有你的ListView只有VerticalScroll定義:

    <ListView Name="myList" ScrollViewer.HorizontalScrollMode="Disabled"> 
    

    當然是可能的兩個方向做,但它是一個簡單的例子。

  3. 現在讓我們來看看一個Page的構造函數:

    PointerPoint firstPoint = null; 
    ScrollViewer listScrollviewer = null; 
    
    public MainPage() 
    { 
        this.InitializeComponent(); 
        myList.ItemsSource = yourItemSource; 
        myList.PointerEntered += myList_PointerEntered; 
        myList.PointerMoved += myList_PointerMoved; 
    } 
    

    沒有什麼奇怪的在這裏 - 我只是訂閱事件,並宣佈兩個變量firstPointlistScrollviewer,我將在以後需要。

  4. 我們也需要得到我們的我們的ListViewScrollViewer - 下面的方法將做的工作:

    public static ScrollViewer GetScrollViewer(DependencyObject depObj) 
    { 
        if (depObj is ScrollViewer) return depObj as ScrollViewer; 
    
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) 
        { 
         var child = VisualTreeHelper.GetChild(depObj, i); 
    
         var result = GetScrollViewer(child); 
         if (result != null) return result; 
        } 
        return null; 
    } 
    
  5. 現在 - 讓我們的活動,我們將需要禁用ScrollViewer

    private ScrollViewer DisableScrolling(DependencyObject depObj) 
    { 
        ScrollViewer foundOne = GetScrollViewer(depObj); 
        if (foundOne != null) foundOne.VerticalScrollMode = ScrollMode.Disabled; 
        return foundOne; 
    } 
    
  6. 我們將在啓動PointerEntered事件時禁用ScrollViewer事件。在這一步中,我們還會記得按下的PointerPoint--因爲我們禁用了Scrollviewer,我們將不得不手動滾動它 - 這就是我們需要這個PointerPoint

    private void myList_PointerEntered(object sender, PointerRoutedEventArgs e) 
    { 
        firstPoint = e.GetCurrentPoint(myList); 
        if (listScrollviewer == null) listScrollviewer = DisableScrolling(myList); 
    } 
    
  7. 最後我們PointerMoved事件,因爲我們已經禁用ScrollViewer現在西港島線被解僱 - 移動ScrollViewer +其他代碼,你需要把有:

    private void myList_PointerMoved(object sender, PointerRoutedEventArgs e) 
    { 
        if (listScrollviewer != null) 
        { 
         PointerPoint secondPoint = e.GetCurrentPoint(myList); 
         double verticalDifference = secondPoint.Position.Y - firstPoint.Position.Y; 
         listScrollviewer.ChangeView(null, listScrollviewer.VerticalOffset - verticalDifference, null); 
        } 
        // some other code you need 
    } 
    

幾句話:

  • 這種方法仍然需要很多調整,但hopefuly將告訴你如何實現自己的目標,
  • 你可能也需要一些小的水平運動與垂直孩子們分開,
  • 如果您ListView或其他控制具有水平滾動,然後您還需要禁用並處理它,
  • 此方法不會像原始ScrollViewer那樣平滑運行。

我也把一個簡單的工作示例here at OneDrive