[번역]내 제스처 어디 갔 지?

원문:http://blogs.msdn.com/b/wsdevsol/archive/2013/02/16/where-did-all-my-gestures-go.aspx
처음 번역 하 는 것 이 니 비 웃 지 마 세 요.번역 에 문제 가 있 으 면 연락 주세요.
제 개인 블 로그 에 오신 것 을 환영 합 니 다.http://blog.s2003zy.com
사용자 들 에 게"collection 컨트롤 에서 pointer 입력 과 처리 이벤트(manipulations)를 어떻게 제어 하 느 냐"는 질문 을 자주 받 습 니 다.예 를 들 어 ListViews,GridViews 또는 FlipViews 에서 응용 프로그램 은 View 의 items 에서 PointerPressed 이 벤트 를 가 져 올 수 있 지만 그 후에 이벤트(pointer events)를 클릭 하면 사라 집 니 다."프로그램 에서 손짓 이나 조작 으로 변환 할 수 없습니다."
이곳 에서 도대체 무슨 일이 일 어 났 습 니까?
이 컨트롤 들 의 공통점 은 스크롤 뷰 어 를 가지 고 있 으 며 스크롤 뷰 어 는 pointer 의 제 어 를 받 아 스크롤 뷰 어 를 스크롤 한 다 는 것 이다.ScrollViewer 가 모든 pointer 와 이벤트 처리(manipulation events)권 을 얻 으 면 프로그램 이 더 이상 제어 할 기회 가 없습니다.
이 는 프로그램 이 스크롤 컨트롤 에서 Pointer 이 벤트 를 처리 해 야 한다 면 scrollViewer 를 disable 해 야 한 다 는 뜻 입 니 다.
왜 ScrollViewer 에서 pointerd 를 가 져 옵 니까?
효율 과 응답 능력,Xaml 은 서로 다른 스 레 드 에서 그들의 도형 을 조합 하고 렌 더 링 합 니 다.렌 더 링 스 레 드 는 화면 을 원활 하 게 업데이트 하 는 것 을 책임 집 니 다.조합 스 레 드 는 프로그램의 UI 가 실행 되 고 컨트롤 의 레이아웃 을 업데이트 할 수 있 는 곳 입 니 다.레이아웃 이 업데이트 되 지 않 을 때마다 렌 더 링 스 레 드 는 시각 적 으로 선명 하고 빠 르 며 다른 작업 이 완료 되 고 있 더 라 도 유지 할 수 있 습 니 다.레이아웃 이 아 닌 업데이트,예 를 들 어 독립 된 애니메이션 과 렌 더 링 변환 은 렌 더 링 스 레 드 에서 완성 할 수 있 으 며 동기 화 두 스 레 드 를 늦 추 지 않 습 니 다.
접촉 사건 은 빠 른 응답 이 필요 하기 때문이다.Xaml 프로그램 은 Direct Manipulation 이라는 프로그램 을 이용 합 니 다. 의 윈도 기능 은 밑바닥 의 렌 더 링 라인 에서 처리 합 니 다.Direct Manipulation 에서 감지 할 수 있 는 터치 이벤트,예 를 들 어 스크롤,이동,크기 조정 등 입 니 다.ScrollViewer 는 이 를 이용 하여 빠르게 스크롤 합 니 다.응용 프로그램 은 렌 더 링 스 레 드 에서 Xaml Manipulation 사건 을 통 해 Direct Manipulation 을 감청 하여 크기 조정,이동,회전 변환 등 렌 더 링 변환 을 실현 하고 빠 른 응답 을 할 수 있 습 니 다.
Pointer 이 벤트 는 바로 그곳 에 갑 니 다.ScrollViewer 가 Pointer Pressed 이 벤트 를 처리 할 때 Direct Manipulation 엔진 이 pointer 의 제 어 를 맡 았 습 니 다.응용 프로그램 은 현재 의 조작 이 끝 날 때 까지 어떠한 Pointer 이벤트 도 받 아들 이지 않 습 니 다.
그럼 프로그램 에 Pointer 정보 가 필요 하면 어떻게 합 니까?
하나의 간단 한 방법 은 하나의 키 요소(예 를 들 어 Image)가 스크롤 을 차단 하고 자신의 통 제 를 받 도록 설정 하 는 것 이다.예 를 들 어 FlipView 의 ItemTemplate 에 있 는 Image 의 ManipulationMode 를'All'(ManipulationMode='All')로 설정 하면 그림 을 터치 하 는 이벤트 가 ScrollViewer 를 터치 하지 않 습 니 다.이 그림 은 Xaml manipulation 이벤트 와 pointer 이 벤트 를 받 아들 여 제스처 인식 처리 프로그램 에 전달 할 수 있 습 니 다.
이벤트 가 하위 요소 에 전달 되 는 데 적용 되 지 않 는 다 면 좀 번 거 로 울 것 이다.가장 좋 은 방법 은 정 보 를 하위 구역 으로 제한 하거나 설정 모드 를 이용 하 는 것 이다.이러한 상황 에서 PointerPressed 처리 자 는 하위 영역 이나 비 스크롤 모드 인지 판단 할 수 있 습 니 다.그러면 시각 화 트 리 를 통 해 ScrollViewer 가 Direct Manipulation 을 끝 내 는 징 크 스 를 찾 을 수 있 습 니 다.
위의 것 을 실현 하기 위해 서 는 ScrollViewer 의 Horizontal ScrollMode 와 Vertical ScrollMode 를 Disabled 로 바 꿔 야 합 니 다.GridView 나 FlipView 의 한 방향의 스크롤(수평 또는 수직)이 있다 면 하나의 맛 만 바 꾸 면 Disabled 가 필요 합 니 다.
ScrollViewer FindParentScrollViewer(DependencyObject start) 
{ 
    DependencyObject item = start; 
    DependencyObject parent = null; 
    do 
    { 
        parent = (DependencyObject)VisualTreeHelper.GetParent(item); 
        if (parent is ScrollViewer) 
        { 
            return parent as ScrollViewer; 
        } 
        item = parent; 
    } while (item != null);

    return null; 
}

 

bool InDisableScrollViewerRegion(PointerPoint pt) 
{ 
    // For demonstration purposes, scroll at the top and block the rest 
    return pt.Position.Y > 400; 
}

private void OnPointerPressed(object sender, PointerRoutedEventArgs e) 
{ 
    DependencyObject depObj = (DependencyObject)e.OriginalSource; 
   
    if (InDisableScrollViewerRegion(e.GetCurrentPoint(this))) 
    { 
        DisableScrolling((DependencyObject)e.OriginalSource); 
    } 
    
    UIElement target = sender as UIElement;

    PointerPoint point = e.GetCurrentPoint(itemFlipView); 
    gestureRecognizer.ProcessDownEvent(point); 
    target.CapturePointer(e.Pointer); 
    e.Handled = true; 
}

ScrollMode _originalScrollMode; 
bool _scrollingDisabled = false; 
private void DisableScrolling(DependencyObject depObj) 
{ 
       ScrollViewer parentElem; 
       parentElem = FindParentScrollViewer(depObj); 
       if (parentElem != null) 
      { 
            _originalScrollMode = parentElem.HorizontalScrollMode; 
            _scrollingDisabled = true; 
            parentElem.HorizontalScrollMode = ScrollMode.Disabled; 
     } 
}

private void RestoreScrolling(DependencyObject depObj) 
{ 
     if (_scrollingDisabled) 
     { 
            _scrollingDisabled = false; 
            ScrollViewer parentElem = FindParentScrollViewer(depObj); 
            if (parentElem != null) 
            { 
                    parentElem.HorizontalScrollMode = _originalScrollMode; 
            } 
     } 
}

 

불 행 히 도 프로그램 이 스크롤 과 제스처 를 동시에 필요 로 한다 면 좋 은 방법 은 아니다.이러한 상황 에서 유일한 선택 은 Pointer 메 시 지 를 가 져 오 는 곳 에서 Direct Manipulation 을 닫 는 것 입 니 다.그러나 이 역시 스크롤 을 무효 화 할 수 있 습 니 다.프로그램 이 스크롤 할 수 있 도록 스크롤 뷰 어의 ScrollToHorizontal Offset 또는 ScrollToVertical Offset(8.1 에서 ChangeView 로 바 뀌 었 습 니 다)를 사용 하여 스크롤 뷰 어의 위 치 를 업데이트 해 야 합 니 다.이것 은 매우 번 거 롭 고 ScrollViewer 가 스스로 일 을 하 게 하 는 것 보다 느 릴 수 있 으 므 로 가능 한 한 피해 야 한다.

좋은 웹페이지 즐겨찾기