2013-02-21 21 views
0

考慮一下:如何防止ScrollViewer處理後代的MouseMove事件? (Silverlight的用於Windows電話)

<ScrollViewer> 
    <!-- Several Controls /--> 

    <MyControl MouseMove="myMouseMoveHandler" /> 

    <!-- Several Controls /--> 
</ScrollViewer> 

MyControl是與在圓周上,其可以旋轉,並且在三角形的選擇的色調的細微差別的顏色光譜的HSV顏色選擇控件。它看起來很棒,但遺憾的是我還無法發佈圖片(代表)。它確實需要能夠處理其表面上所有方向的鼠標移動。

現在,當我在MyControl上移動鼠標(並正確處理移動時),ScrollViewer仍然滾動!

即使它是ScrollViewer中的唯一控件,運動在我的控件內部開始和結束,並且/或者在MouseLeftButtonDown/Up事件中設置了e.Handled = true,也會發生這種情況。使用..Down中的CaptureMouse()和..Up中的ReleaseMouseCapture()也沒有幫助。你會同意我不能更改ScrollViewer的實現(或者我可以嗎?),並且我不能保證我的控件永遠不會被託管在ScrollViewer中(例如,因爲我想發佈它)。

必須有可能阻止ScrollViewer獲取MouseMove。證明:只需將MyControl替換爲一個包含更多項目而不是其高度的ListBox,並且您可以滑過列表框項目而無需ScrollViewer作出反應。

但是如何?它是否也是ListBox中的ScrollViewer,這就是它在那裏工作的原因,或者它也可以用於我的控制嗎?

回答

1

好的,我找到了一個很好的解決方案。

我的想法被固定到e.Handled(MouseMove中不可用),IsHitTestVisible(隱藏所有觸摸事件中的孩子)以及各種各樣的東西,我沒有看到明顯的東西。

這裏是有人的情況下的代碼具有相同的問題:

struct ScrollVisibilities 
{ 
    public ScrollBarVisibility Horizontal; 
    public ScrollBarVisibility Vertical; 
} 

Dictionary<ScrollViewer, ScrollVisibilities> scrollersStates = new Dictionary<ScrollViewer, ScrollVisibilities>(); 

bool scrollersDisabled; 

void disableScrollViewers(bool disable) 
{ 
    if (scrollersDisabled == disable) // can't disable if disabled or enable if enabled 
     return; 
    scrollersDisabled = disable; 

    if (disable) 
    { 
     DependencyObject dpo = Parent; 
     while (dpo is FrameworkElement) 
     { 
      if (dpo is ScrollViewer) 
      { 
       ScrollViewer s = dpo as ScrollViewer; 
       ScrollVisibilities v = new ScrollVisibilities() 
       { 
        Horizontal = s.HorizontalScrollBarVisibility, 
        Vertical = s.VerticalScrollBarVisibility 
       }; 
       scrollersStates.Add(s, v); 
       s.HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled; 
       s.VerticalScrollBarVisibility = ScrollBarVisibility.Disabled; 
      } 
      dpo = ((FrameworkElement)dpo).Parent; 
     } 
    } 
    else // restore 
    { 
     foreach (ScrollViewer s in scrollersStates.Keys) 
     { 
      s.HorizontalScrollBarVisibility = scrollersStates[s].Horizontal; 
      s.VerticalScrollBarVisibility = scrollersStates[s].Vertical; 
     } 
     scrollersStates.Clear(); 
    } 
} 

在的MouseLeftButtonDown,我disableScrollViewers(真),並且鉤到Touch.FrameReported。 在Touch_FrameReported中,當所有接觸點都有動作== Up時,disableScrollViewers(false)。這樣,即使發生在MyControl外部,我也會收到Up事件。

這種方法有一些限制,因爲禁用ScrollViewer會導致他們跳到他們(和他們的孩子)未滾動的狀態。所以我把MyControl放在頂部,並相應地設置所有的路線。

相關問題