2013-12-10 7 views
0

wpf 응용 프로그램을 작성 중이며 F1 도움말 지원을 추가하려고합니다. wpf f1 도움말이 모든 사용자 정의 컨트롤에서 작동하지 않습니다.

나는이 very usefull class by Nigel Shaw

나는 마이크로 소프트 HTML 도움말 제작과 테스트 도움말 CHM 파일을 작성했습니다.

나는 그것을 내 응용 프로그램에 통합했습니다. 주 윈도우, 사용자 정의 컨트롤 (CC1)을 메인 윈도우에 동적으로 추가하고 CC1에 동적으로 추가하는 다른 사용자 정의 컨트롤 (CC2)에 HelpTopic을 설정했습니다.

메인 창에서 F1 키를 누르면 올바른 도움말 제목이 열립니다. CC1에서 F1을 누르면 올바른 도움말 제목이 열립니다. CC2에서 F1 키를 누르면 CC1의 도움말 제목이 표시됩니다.

내가 GetHelpTopic 함수가 호출 될 때 제어 스택을 얻기 위해 일부 코드를 추가하고 이것이 I 얻을 무엇 ([0] F1 잡을 제어되는) 우선

[0] System.Windows.Controls.ScrollViewer 
[1] System.Windows.Controls.Grid 
[2] System.Windows.Controls.Grid 
[3] System.Windows.Controls.Grid 
[4] CC1 
[5] System.Windows.Controls.Canvas 
[6] System.Windows.Controls.ScrollViewer 
[7] System.Windows.Controls.Grid 
[8] System.Windows.Controls.Grid 
[9] CustomPanel 
[10] System.Windows.Controls.TabItem 
[11] System.Windows.Controls.TabControl 
[12] System.Windows.Controls.Grid 
[13] MainWindow 

를 I 생각 아마도 ScrollViewer가 F1을 잡아서 더 깊숙이 들어가는 것을 막을 것입니다. 그런데 [6]에서 시작하는 스택을 얻었을 것입니다.

그런 다음 문제는 CC1과 CC2 클래스의 차이에서 비롯된 것일 수 있습니다. 내가 더 가까워지고 있어요 : 은 그러나 그들은 모두 업데이트 1


UserControl을

UserControl - UserControlXY - AnimatedControl - AnimatedControlValidated - CC1 

UserControl - UserControlXY - AnimatedControl - AnimatedControlValidated - AnimatedStructure - CC2 
에서 상속 같은 기본 클래스에서 상속합니다. 내가 CC2의 컨트롤 안쪽을 클릭하면 후 나는 다음과 같은 스택

[0] System.Windows.Controls.TextBox 
[1] System.Windows.Controls.Grid 
[2] System.Windows.Controls.Grid 
[3] CC2 
[4] System.Windows.Controls.Canvas 
[5] System.Windows.Controls.ScrollViewer 
[6] System.Windows.Controls.Grid 
[7] System.Windows.Controls.Grid 
[8] System.Windows.Controls.Grid 
[9] CC1 
[10] System.Windows.Controls.Canvas 
[11] System.Windows.Controls.ScrollViewer 
[12] System.Windows.Controls.Grid 
[13] System.Windows.Controls.Grid 
[14] CustomPanel 
[15] System.Windows.Controls.TabItem 
[16] System.Windows.Controls.TabControl 
[17] System.Windows.Controls.Grid 
[18] MainWindow 

을 얻을 그리고 CC2에 대한 올바른 도움말 항목을 얻을. CC2를 클릭했을 때 초점을 맞추는 것이 문제라고 생각합니다.

그래서 나는 CC2에 다음 태그 추가 :

Focusable="True" 

을하지만 CC2 배경 또는 요소하지 포커스를 클릭하면이 경우에 나는 여전히 이전에 잘못된 동작을 얻을 수 (예 : 라벨) ...

그래서 다음에 내가 이벤트가이 일을 통해 초점을 수동으로

MouseLeftButtonDown += new System.Windows.Input.MouseButtonEventHandler(AnimatedStructure_MouseLeftButtonDown); 

을 설정하는 MouseLeftButtonDown을 추가 :

,536,913,632 10
private void AnimatedStructure_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) 
{ 
    this.Focus(); 
} 

하지만이 경우에도 여전히 이전에 잘못된 도움말 항목을 얻고 있습니다 ...


업데이트 2 :

나는 또한이 같은 FocusManager를 사용하는 AnimatedStructure_MouseLeftButtonDown을 수정

GotFocus += new System.Windows.RoutedEventHandler(AnimatedStructure_GotFocus); 
LostFocus += new System.Windows.RoutedEventHandler(AnimatedStructure_LostFocus); 

내가 CC2에 추가이 시간 : 나는에 중단 점을 넣어

FocusManager.SetFocusedElement(this.Parent, this); 

GotFocus 및 LostFocus. CC2 내부를 클릭하면 GotFocus가 FocusManager에 의해 올바르게 실행됩니다 (AnimatedStructure_MouseLeftButtonDown ). 그 직후에 CC2 자체에서 LostFocus가 수신됩니다. RoutedEventArgs를 보았습니다. 실제로 자체 포커스를 제거하는 것은 CC2 자체입니다.

그래서 지금은 조금 그 때문에 내가

답변

0

문제와 simple blog entry

하나의 솔루션을 주셔서 감사합니다 마지막으로 발견 지금까지 당신이 쓴 누구 수없는 ... 수행 할 작업에 대한 손실입니다 그 블로그 항목.

짧은 대답 : WPF 포커스 메커니즘이 잘못되었습니다.

오랫동안 답을 얻으려면 글쓴이가 내가 경험 한 행동이 일어난 이유에 대한 세부 정보를 제공하므로 블로그를 읽으십시오.

나는 내 솔루션

static class FocusHelper 
{ 
    private delegate void MethodInvoker(); 

    public static void Focus(UIElement element) 
    { 
     //Focus in a callback to run on another thread, ensuring the main UI thread is initialized by the 
     //time focus is set 
     ThreadPool.QueueUserWorkItem(delegate(Object foo) { 
      UIElement elem = (UIElement)foo; 
      elem.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, 
       (MethodInvoker)delegate() 
      { 
       elem.Focus(); 
       Keyboard.Focus(elem); 
      }); 
     }, element); 
    } 
} 

에 다음 클래스를 addedf 그리고이 속임수를 썼는지

MouseLeftButtonDown += new System.Windows.Input.MouseButtonEventHandler(AnimatedStructure_MouseLeftButtonDown); 

private void AnimatedStructure_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) 
{ 
    FocusHelper.Focus(this); 
} 

CC2

있다. 이제 CC2에서 포커스가 올바르게 설정되고 유지 관리되며 올바른 도움말 토픽을 얻습니다.

만세!