2013-10-22 1 views
4

DataTemplate에서 SelectedRadioButton을 가져 오려고합니다.시각적 트리에서 컨트롤 찾기

enter image description here

및 코드 :

WPF 검사기는 시각적 트리 보였다

void menu_StatusGeneratorChanged(object sender, EventArgs e) 
      { 
       var status = Menu.Items.ItemContainerGenerator.Status; 
       if (status == System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated) 
       { 
        var item = Menu.Items.ItemContainerGenerator.ContainerFromIndex(0); 
        // item is a ContentPresenter 
        var control = Tools.FindChild<SelectedRadioButton>(item); 
        control = Tools.FindAncestor<SelectedRadioButton>(item); 
       } 
      } 

item은 ContentPresenter에, WPF 관리자의 이미지를 볼 수 있습니다를, 내가해야 거기에서 생각 SelectedRadioButton에 도달 할 수 있습니다. 변수 control은 항상 null입니다.
여기에 무엇이 누락 되었습니까? 나는이 visualtreehelpers을 사용합니다.

+1

WPF에서 이와 같은 UI 요소를 조작하는 것은 매우 드뭅니다 **. 너 뭐하려고? –

+0

해당 메서드 내에 중단 점을 설정하고 WPF Tree Virtualizer를 사용하여 디버거가 중단 점에 도달하는 시점에 VisualTree를 확인합니다. 전체 VisualTree가 완전히로드되지 않았을 수 있으며 WPF Tree Vitualizer도 null을 표시합니다. Virtualizer가 구체적인 인스턴스를 표시하는 경우 FindChild를 잘못 사용했을 수 있습니다. WPF Tree Virtualizer를 확인하십시오. http://blogs.msdn.com/b/zainnab/archive/2010/01/29/using-the-wpf-tree-visualizer-vstipdebug0004.aspx 불행하고 최악의 경우가 될 수 있습니다. 여기서 발전기는 끝났지 만 컨테이너의 측정은 아직 실행되지 않았습니다. –

+0

@HighCore 초기화를 위해 내 사용자 지정 컨트롤 중 하나의 속성을 설정하려고합니다. 그러나 ItemsControl의 DataTemplate을 통해 생성되며 액세스 지점이 없습니다. – Gerard

답변

8

비주얼 트리를 탐색하는 데 사용한 코드에서 트리의 FrameworkElementApplyTemplate() 메서드를 사용하지 않아서 cildren을 찾을 수 없습니다. 내 상황에서 다음 코드는 작동합니다 (I 그것을 놓친) 그 지적에 "dev에 고슴도치"의 의견

/// <summary> 
    /// Looks for a child control within a parent by name 
    /// </summary> 
    public static DependencyObject FindChild(DependencyObject parent, string name) 
    { 
     // confirm parent and name are valid. 
     if (parent == null || string.IsNullOrEmpty(name)) return null; 

     if (parent is FrameworkElement && (parent as FrameworkElement).Name == name) return parent; 

     DependencyObject result = null; 

     if (parent is FrameworkElement) (parent as FrameworkElement).ApplyTemplate(); 

     int childrenCount = VisualTreeHelper.GetChildrenCount(parent); 
     for (int i = 0; i < childrenCount; i++) 
     { 
      var child = VisualTreeHelper.GetChild(parent, i); 
      result = FindChild(child, name); 
      if (result != null) break; 
     } 

     return result; 
    } 

    /// <summary> 
    /// Looks for a child control within a parent by type 
    /// </summary> 
    public static T FindChild<T>(DependencyObject parent) 
     where T : DependencyObject 
    { 
     // confirm parent is valid. 
     if (parent == null) return null; 
     if (parent is T) return parent as T; 

     DependencyObject foundChild = null; 

     if (parent is FrameworkElement) (parent as FrameworkElement).ApplyTemplate(); 

     int childrenCount = VisualTreeHelper.GetChildrenCount(parent); 
     for (int i = 0; i < childrenCount; i++) 
     { 
      var child = VisualTreeHelper.GetChild(parent, i); 
      foundChild = FindChild<T>(child); 
      if (foundChild != null) break; 
     } 

     return foundChild as T; 
    } 

감사합니다.
프로덕션 코드에서이 접근 방식을 사용하지 않을 것이므로 "HighCore"와 같은 데이터 바인딩을 사용해야합니다.

관련 문제