2010-02-18 6 views
27

FindName 나를 위해 고장 안 때 :(당신이 그런 일에 전문가 인 경우WPF -이

내가 도움을 사랑 FindName는 null를 돌려줍니다

내가 찾고 있어요 목적이있다.. 내가 가진 증거 여기

는 시나리오이다.

ToggleButton button = (ToggleButton)sender; 
Popup popup = (Popup)button.FindName("popSelectIteration"); 

popup가 null 항상은 아니지만 그냥 가끔하지만 내가 익어 나는 아이를 null로 설정된 경우에도.. 거기에있다.

null 일 때 중단 점을 넣고이 두 스크린 샷을 찍었습니다.

alt text http://img175.imageshack.us/img175/2055/popupisnull.png

하지만 시계 파고 경우, 당신이 볼 수있는 아이가 있음 :

alt text http://img708.imageshack.us/img708/8757/watchwithpopupnull.png

FindName은 "popSelectIteration"에 대한 null이 반환되는 경우

입니다 그래서 나는 무엇을 놓치고 있습니까? FindName이 왜 그것을 찾지 못합니까? 스크린 샷에서 볼 수 있듯이 이것은 타이밍 문제가 아닙니다 (FindName 시계는 null이지만 직접 경로는 괜찮습니다).

컨트롤을 찾는 더 좋은 방법이 있습니까?

사이드 노트 : 해당 토글 버튼에 대해 XAML에서 상호 작용하는 경우이 질문에서 확인할 수 있습니다 : WPF - FrameworkElement - Enumerate all decendents?.


업데이트 :이 작동 약간의 시간과 다른 시간에 실패한 이유를 파고 일부를했다. NameScope.SetNameScope((DependencyObject)form, new NameScope()); (전체 메서드 코드 here)이라는 애니메이션이 있습니다. 해당 호출 바로 뒤에 FindName이 실패하기 시작합니다.

나는 그 전화를 정말로 이해하지 못한다. 코드를 복사하여 붙여 넣은 것 같습니다. 어쨌든, 나는 그것을 주석 처리했다. 그러나 나는 이것이 왜 실패하고 있는지 알고 싶을 것이다.

답변

30

시각적 트리와 논리적 트리의 차이점과 관련이 있다고 생각합니다. 컨트롤이 논리 트리에 있지만 어쩌면이 컨트롤에 대한 템플릿이 아직 적용되지 않았으므로 FindName이 유용한 것을 반환하지 않습니다.

ApplyTemplate()을 호출 해 볼 수 있습니다. 먼저 컨테이너에.

이렇게하면 때때로 뭔가를 반환하는 이유도 설명 할 수 있습니다.

+0

나를 위해 일했습니다. Template.FindName()으로이 문제가 발생했습니다 – Trap

+0

이것은 저에게 효과적이었습니다. 처음에는 숨겨진 컨트롤이나 처음에는 볼 수 없었던 탭에서 더 많은 문제가있었습니다. – Dave

+0

ComboBox가있는 GetTemplateChild ("PART_EditableTextBox")에 문제가 있습니다. ApplyTemplate()을 호출하면 문제가 해결되었습니다. 감사! –

1

일부 컨트롤에 적용된 DataTemplate에서 뭔가를 찾으려고 할 때 문제가되는 FindName 함수를 사용하지 않는 것이 좋습니다. 대신 소프트웨어 구조에 따라 XAML에서 Popup을 선언하고 을 리소스처럼 참조하거나 Binding을 사용하여 일부 Model 속성을 참조로 설정합니다. 행운을 비네.

28

지금 같은 질문을 충족 ​​가지고,하지만 난 방법을 아래와 같이 사용 button.FindResource("popSelectIteration")

+1

그냥 나에게 일어난다! 나는 그것에 2 시간을 소비한다, 마침내, 나는 당신의 방법과 작품을 시험해 본다! !! – Cheung

-1

시도를보십시오 : 컨트롤이 동적 인 경우

#region Override - OnApplyTemplate 

    public override void OnApplyTemplate() 
    { 
     base.OnApplyTemplate(); 

     this.PART_ListViewLeft  = GetTemplateChild(cPART_ListViewLeft)  as ListView; 
     this.PART_ListViewCenter = GetTemplateChild(cPART_ListViewCenter) as ListView; 
     this.PART_ListViewRight  = GetTemplateChild(cPART_ListViewRight)  as ListView; 

     this.PART_GridViewLeft  = GetTemplateChild(cPART_GridViewLeft)  as DsxGridView; 
     this.PART_GridViewCenter = GetTemplateChild(cPART_GridViewCenter) as DsxGridView; 
     this.PART_GridViewRight  = GetTemplateChild(cPART_GridViewRight)  as DsxGridView; 
     if(this.PART_ListViewLeft!=null) 
      this.PART_ListViewLeft  .AlternationCount = this.AlternatingRowBrushes.Count; 
     if(this.PART_ListViewCenter!=null) 
      this.PART_ListViewCenter .AlternationCount = this.AlternatingRowBrushes.Count; 
     if(this.PART_ListViewRight!=null) 
      this.PART_ListViewRight  .AlternationCount = this.AlternatingRowBrushes.Count; 
     // ApplyTempleted = true; 
     CreateColumnLayout(); 
    } 
    #endregion 

만들고 'Visibility'가 숨겨 지거나 접히도록 설정된 컨테이너 또는 그 다음 코드 인 "this.PART_ListViewLeft = GetTemplateChild (cPART_ListViewLeft) as ListView;" 이유는 분명히 null을 반환합니다. OnApplyTemplate이 호출되기 전에 datatemplete가 아직 적용되지 않았습니다 !!!!!!! 귀하의 질문은 동일해야합니다! 행운을 빈다!

1

를 사용하는

LogicalTreeHelper.FindLogicalNode(button, "popSelectIteration"); 
5

제 경험상, 코드 숨김을 통해 항목을 추가하면 이러한 현상이 발생합니다. 나는 당신이 이름 범위를 통해 FindName() (또는 애니메이션 프레임 워크)을 속일 수 있다는 것을 발견했다. 나중에 참조 할 수 있도록이 게시

NameScope.GetNameScope(yourContainer).UnregisterName("name of your control"); 

: 그것은 당신이 컨트롤을 만들 때, 당신은하지만, 당신이 이름의 등록을 취소 있는지 확인해야합니다, 안정적으로 작동이 들어

NameScope.GetNameScope(yourContainer).RegisterName("name of your control", yourControlInstance); 

를 수행합니다.