2012-05-04 6 views
0

내 wpf 응용 프로그램에서 키보드 탐색에 문제가 있습니다. 간체 나는 화면 너비의 약 4 분의 1을 차지하는 메뉴 항목 목록이있는 가로 스택 패널이 있습니다.wpf 키보드 탐색 동작

바로 아래에서 화면의 전체 너비를 차지하는 콘텐츠 컨트롤이 있습니다.

콘텐츠 컨트롤은 강조 표시된 메뉴 항목을 기반으로로드 된 사용자 정의 컨트롤을 변경합니다. 모든 사용자 컨트롤이 문제는 내가 StackPanel의에서 아래로 키를 누를 때 그것이 바로 아래에 내부 그리드 컬럼에 포커스를 시도한다는 것입니다

<Grid> 
    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="Auto" /> 
      <ColumnDefinition Width="*" /> 
     </Grid.ColumnDefinitions> 
     <Grid Grid.Column="0" /> 
     <Grid Grid.Column="1" /> 
    </Grid> 
</Grid> 

의 형태로 설정입니다. 첫 번째 열에는 포커스 가능 항목이 있지만 두 번째 열에는 포커스가없는 항목이 있습니다. 첫 번째 열 바로 위에 있지만 처음에는 두 번째 열 바로 위에있는 메뉴 항목에 도달하고이 지점에서 아래로 탐색 할 수없는 스택 패널의 첫 번째 메뉴 항목 두 개는 정상적으로 작동합니다.

외부 격자를 위의 xaml과 같이 추가했지만 이것이 도움이되지 않았습니다. 포커스가 눈금 (또는 안쪽 눈금)에서 사용할 수있는 첫 번째 포커스 가능 요소로 이동하지 않는 이유와 눈금 1에 포커스를 강제로 적용하는 방법은 무엇입니까?

내 viewmodel에서이 작업을 수행 할 수 있다고 생각하지만 비슷한 문제를 겪고있는 상당수의 페이지가 있으므로 모든 키보드 탐색을 완전히 다시 작성하고 제어하는 ​​것보다 쉬운 솔루션이 필요했습니다.

도움을 주시면 감사하겠습니다.

업데이트 : 첫 번째 그리드에서 focuasable을 true로 설정하면 네비게이션이 작동하고 1 열에서 끝나지만 분명히 첫 번째 키를 누르면 "눈에 띄게"표시되어 포커스가 그리드에 제공 될 때 아무 것도하지 않습니다. 비슷한 동작을 원하지만 내비게이션이 그리드를 1 열로 똑바로 뛰어 넘길 원합니다.

답변

0

내 솔루션을 게시 할 예정입니다. 나는 해킹 비트처럼 보이지만 더 좋은 것을 얻을 때까지 여전히 만족스럽지 않다. ..... 위에서 언급했듯이 키보드 탐색은 주변의 그리드와 함께 작동하는 것처럼 보이지만 그리드는 원하지 않는다. 집중해야합니다. 내가 한 것은 그리드를 확장하는 사용자 지정 컨트롤을 만드는 것입니다. 키보드 포커스를 오버라이드 한 다음 포커스가 마지막으로있는 요소를 확인하고 그리드 외부에 있는지 확인합니다 (I.E. 그리드로 이동 중입니다). 그럴 경우 초점이 어느 방향에서 왔는지를 봅니다. 예를 들어 PredictFocus가 위쪽 및 왼쪽 키 누르기에서 올 수 있다고 나는 말할 수 있습니다. 이것이이 해법이 좀 이상하다고 생각하는 이유입니다. 방향이 발견되면 그 방향으로 다시 한 번 초점을 이동합니다. 이 작업을 수행하려면 그리드에서 포커스가 있어야합니다.

protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e) 
    { 
     UIElement previousFocus = (UIElement)e.OldFocus; 
     if (previousFocus != null) 
     { 
      if (!previousFocus.IsDescendantOf(this)) 
      { 
       if (previousFocus.PredictFocus(FocusNavigationDirection.Up).Equals(this)) 
       { 
        this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Up)); 
       } 
       else if (previousFocus.PredictFocus(FocusNavigationDirection.Down).Equals(this)) 
       { 
        this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Down)); 
       } 
       else if (previousFocus.PredictFocus(FocusNavigationDirection.Left).Equals(this)) 
       { 
        this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Left)); 
       } 
       else if (previousFocus.PredictFocus(FocusNavigationDirection.Right).Equals(this)) 
       { 
        this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Right)); 
       } 
      } 
     } 
     base.OnGotKeyboardFocus(e); 
    }