2012-11-21 2 views
2

대부분의 경우 완벽하게 잘 수행되는 System.Windows.Controls.Control에서 파생 된 사용자 정의 wpf 컨트롤이 있습니다.UIElement.IsVisible == false 사용자 정의 컨트롤에 대해 포커스를 맞출 수 없습니다.

그러나 때때로 UIElement.Focus()를 호출하는 컨트롤에서 x.Focus()를 호출하면 false가 반환되고 컨트롤에 포커스가 맞추어지지 않습니다.

일부 굴착 후 나는

컨트롤 렌더링
var x = control as FrameworkElement; 
var focusable = x.Focusable; // -> true 
var enabled = x.IsEnabled; // -> true 
var visible = x.IsVisible; // -> FALSE <- !!! ARRGG 

, 난 totaly UI에서 볼 수 있음을 발견 하였다. Focus() 호출을 Dispatcher에 넣으려고했는데, 컨트롤에서 UpdateLayout()을 호출 해 보았습니다.

재미있는 부분은 내가 Snnop가에서 IsVisible 속성을 확인하기 위해 사용하는 경우, 스눕 그것이

내가 다른 곳에서 내 컨트롤 구현에 분명 뭔가를 놓치거나나요 :) 사실로보고 있다는입니까? 컨트롤을 제안 사람들을 위해 지금까지 의견

편집 2012년 11월 22일이

덕분에, 완벽하게 하나

var x = control as FrameworkElement; 
x.Dispatcher.Invoke(new Action(() => 
{ 
var isVisible = fe.IsVisible; // -> False 
var focused = fe.Focus(); // -> False 
}), DispatcherPriority.ApplicationIdle); 

이 않았나 도움

렌더링되지 않았을 수 있습니다.

+0

해당 코드를 언제 실행하려고합니까? Snoop을 사용하면 IsVisible은 사실이지만 앱이 유휴 상태 일 때 (즉, measure/arrange/render가 완료된 경우) 표시됩니다. UpdateLayout을 호출하면 해당 호출이 무시되는 시간이 있기 때문에 반드시 도움이되지는 않습니다 (예 : 측정/정렬 패스에있을 때). 어쩌면 당신은 그 전화를 걸고 어디서나 BeginInvoke를해야한다. 아니면 IsVisibleChanged를 훅 (hook)하고 그것을 보이기를 기다려야한다. – AndrewS

+0

@AndrewS, 편집 참조 – Dominik

+0

컨트롤은 어디에서 오는가? 스누프에서 체크인하는 것과 동일한 요소 인스턴스가 확실합니까? 예를 들어이 요소가 템플리트의 요소 일 경우 어쩌면 새 템플리트가 적용되었을 수 있습니다. visualtreehelper 또는 wpf 트리 비주얼 라이저를 사용하여 시각적 트리를 따라 가보고 실제로 시각적 트리에 있는지 확인하고이 요소와 모든 시각적 인 조상의 가시성이 붕괴되지 않았는지 확인하십시오. – AndrewS

답변

0

언제 IsVisible을 false로 확인 했습니까? 컨트롤이 완전히 초기화되고로드 되었습니까? 스눕 (snoop)이 사실이라고 생각한다면 그것은 반드시 있어야합니다 :) 그리고 언제 당신은 컨트롤을 집중하려고합니까? 완전히 초기화되지 않은 상태에서 집중하려고하면 제대로 작동하지 않는 합리적인 이유가있을 수 있습니다.

어쨌든 UIElement.Focus 대신 Keyboard.Focus 메서드를 사용하여 컨트롤을 선택하십시오.

Keyboard.Focus(x); 
+0

이미 UIElement.Focus()와 같은 결과가 나타났습니다. 예, 컨트롤이 완전히 초기화되고로드되었습니다. – Dominik

+0

문제를 재현 할 수있는 작은 코드를 제공해 주시겠습니까? – Sisyphe

+0

컨트롤은 더 큰 응용 프로그램 프레임 워크의 일부입니다. 분리하고 재현하려고 시도합니다. – Dominik

0

나는 같은 문제가 있었는데, 그 원인을 알지 못했습니다. 해결 방법으로 해결했습니다.

스타일에서 가시성을 축소로 설정 한 다음로드 된 이벤트에서 표시로 설정합니다. 이 방법이 모든 용도에 이상적이지는 않지만 다른 사람이이 문제를 접한다면 해결 방법을 시도해 볼 수 있습니다. 컨트롤이 표시되었을

// Set to visible on load 
Loaded += delegate 
{ 
    Dispatcher.BeginInvoke(new Action(() => Visibility = Visibility.Visible)); 
}; 


<!-- By default set to Collapsed --> 
<Style TargetType="{x:Type MyCustomTypeThatIsMisbehaving}"> 
    <Setter Property="Visibility" Value="Collapsed"/> 
</Style> 

, 화재 IsVisibleChanged 다음부터, 당신이 기본 클래스의 메서드를 호출

1

모든 override들에 대한 MSDN 설명서를 확인하게 잘 작동 보인다 필요한 경우. 은 MSDN 명확하게 진술에도 불구하고, 나는 OnVisualParentChanged을 무시하고 하지 호출 (내 경우에는 FrameworkElement) 기본 클래스를했다 :

난 그냥 같은 문제가 있었다 거의 너트 가고 난 후에 나는 범인을 발견

항상이 동작을 유지하려면 기본 구현을 호출하십시오. 다른 요소의 자식이 으로 선언 된 경우이 요소의 요소 트리 동작이 예상과 다를 수 있습니다.base.OnVisualParentChangedIsVisible 속성과 IsVisibleChanged 이벤트를 호출을 추가 한 후

는 예상대로 작동하기 시작했다.

관련 문제