2013-02-21 1 views
0

이 있다면 :ScrollViewer가 자손의 MouseMove 이벤트를 처리하지 못하게하는 방법은 무엇입니까? (윈도우 전화 용 실버)

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

    <MyControl MouseMove="myMouseMoveHandler" /> 

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

MyControl 회전 할 수있는 원형, 삼각형의 선택한 색상의 뉘앙스 컬러 스펙트럼을 갖는 HSV 색 선택 제어한다. 그것은 굉장해 보인다. 그러나 슬프게도 나는 그림을 아직 게시 할 수 없다 (담당자). 표면의 모든 방향에서 마우스 움직임을 처리 할 수 ​​있어야합니다.

이제 MyControl에서 마우스를 움직일 때 (그리고 움직임을 올바르게 처리 할 때), ScrollViewer는 여전히 스크롤됩니다!

ScrollViewer에서 유일한 컨트롤 일 때도 이동이 시작되고 끝나고 컨트롤 내에서 끝나거나 MouseLeftButtonDown/Up 이벤트에서 e.Handled = true로 설정하는 경우에도 발생합니다. ..Up의 ..Down 및 ReleaseMouseCapture()에서 CaptureMouse()를 사용하면 도움이되지 않습니다.

ScrollViewer 구현을 변경할 수 없다는 것에 동의합니까? 그렇습니다. ScrollViewer 내에서 내 컨트롤이 호스팅되지 않는다고 보장 할 수 없습니다 (예 : 게시하고 싶습니다.).

ScrollViewer가 MouseMove를 가져 오는 것을 방지 할 수 있어야합니다. 증명 : 단순히 MyControl을 Height에 맞는 것보다 많은 항목이 포함 된 ListBox로 교체하면 ScrollViewer가 반응하지 않고 ListBox 항목을 스 와이프 할 수 있습니다.

하지만 어떻게? ListBox 내부의 ScrollViewer이기 때문에 그것이 작동하는지 또는 내 제어를 위해 할 수 있습니까?

답변

1

좋아, 나는 잘 작동하는 해결책을 발견했다.

내 생각이 e.Handled (MouseMove에서는 사용할 수 없음), IsHitTestVisible (터치 이벤트에서 모든 자식을 숨김) 및 여러 가지 요소로 고정되어 있으므로 눈에 띄지 않았습니다. MouseLeftButtonDown에서

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(); 
    } 
} 

, (진정한) I disableScrollViewers 및 Touch.FrameReported에 훅 : 여기

사례 누군가의 코드가 같은 질문을 가지고있다. Touch_FrameReported에서 모든 터치 포인트에 Action == Up이 있으면 ScrollViewers (false)를 비활성화합니다. 그렇게하면 MyControl의 외부에서 발생하더라도 Up 이벤트가 발생합니다.

ScrollViewer를 사용하지 않도록 설정하면 스크롤되지 않은 상태로 이동할 수 있으므로이 방법에는 제한이 있습니다. 그래서 MyControl을 맨 위에 놓고 그에 따라 모든 정렬을 설정합니다.

관련 문제