2013-06-28 26 views
1

提及FrameworkElement的我有一个嵌套ItemsControl,显示以下型号:获取嵌套ItemsControls

public class Parent 
{ 
    public string ParentTitle 
    { 
     get; 
     set; 
    } 

    ICollection<Child> Children 
    { 
     get; 
     set; 
    } 
} 

public class Child 
{ 
    public string ChildTitle 
    { 
     get; 
     set; 
    } 
} 

ItemsControl看起来像这样:

<ItemsControl x:Name="listOfParents"> 
    <ItemsControl.ItemTemplate> 
      <DataTemplate DataType="{x:Type local:Parent}"> 
       <Grid> 
        <Grid.RowDefinitions> 
         <RowDefinition Height="Auto"/> 
         <RowDefinition Height="*"/> 
        </Grid.RowDefinitions> 

        <Button x:Name="btnTarget" Grid.Row="0" Content="{Binding ParentTitle}"></Button> 

        <ItemsControl Grid.Row="1" ItemsSource="{Binding Children}"> 
         <ItemsControl.ItemTemplate> 
          <DataTemplate DataType="{x:Type local:Child}"> 
           <Button x:Name="btnSource" Content="{Binding ChildTitle}" /> 
          </DataTemplate> 
         </ItemsControl.ItemTemplate> 
        </ItemsControl> 
       </Grid> 
      </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

listOfParents Itemssouce是List<Parent>。我如何访问Buttonbtn目标btnSource被点击?

回答

1

您可以用FindChild()访问Button

上市的功能:

public static T FindChild<T>(DependencyObject parent, string childName) where T : DependencyObject 
    { 
     if (parent == null) 
     { 
      return null; 
     } 

     T foundChild = null; 

     int childrenCount = VisualTreeHelper.GetChildrenCount(parent); 

     for (int i = 0; i < childrenCount; i++) 
     { 
      var child = VisualTreeHelper.GetChild(parent, i); 
      T childType = child as T; 

      if (childType == null) 
      { 
       foundChild = FindChild<T>(child, childName); 

       if (foundChild != null) break; 
      } 
      else 
       if (!string.IsNullOrEmpty(childName)) 
       { 
        var frameworkElement = child as FrameworkElement; 

        if (frameworkElement != null && frameworkElement.Name == childName) 
        { 
         foundChild = (T)child; 
         break; 
        } 
        else 
        { 
         foundChild = FindChild<T>(child, childName); 

         if (foundChild != null) 
         { 
          break; 
         } 
        } 
       } 
       else 
       { 
        foundChild = (T)child; 
        break; 
       } 
     } 

     return foundChild; 
    } 

呼叫被制造成:

private void btnSource_Click(object sender, RoutedEventArgs e) 
    { 
     Button MyBtnTarget = FindChild<Button>(listOfParents, "btnTarget"); 

     MessageBox.Show(MyBtnTarget.Content.ToString());   
    } 

但这种方式,该功能将选择第一个按钮,我们需要访问所有的元素。为此,我重写了该函数,以便它返回列表中的所有元素。下面的代码:

public static void FindChildGroup<T>(DependencyObject parent, string childName, ref List<T> list) where T : DependencyObject 
    { 
     // Checks should be made, but preferably one time before calling. 
     // And here it is assumed that the programmer has taken into 
     // account all of these conditions and checks are not needed. 
     //if ((parent == null) || (childName == null) || (<Type T is not inheritable from FrameworkElement>)) 
     //{ 
     // return; 
     //} 

     int childrenCount = VisualTreeHelper.GetChildrenCount(parent); 

     for (int i = 0; i < childrenCount; i++) 
     { 
      // Get the child 
      var child = VisualTreeHelper.GetChild(parent, i); 

      // Compare on conformity the type 
      T child_Test = child as T; 

      // Not compare - go next 
      if (child_Test == null) 
      { 
       // Go the deep 
       FindChildGroup<T>(child, childName, ref list); 
      } 
      else 
      { 
       // If match, then check the name of the item 
       FrameworkElement child_Element = child_Test as FrameworkElement; 

       if (child_Element.Name == childName) 
       { 
        // Found 
        list.Add(child_Test); 
       } 

       // We are looking for further, perhaps there are 
       // children with the same name 
       FindChildGroup<T>(child, childName, ref list); 
      } 
     } 

     return; 
    } 
} 

调用函数:

private void btnSource_Click(object sender, RoutedEventArgs e) 
    {    
     // Create the List of Button 
     List<Button> list = new List<Button>(); 

     // Find all elements 
     FindChildGroup<Button>(listOfParents, "btnTarget", ref list); 
     string text = ""; 

     foreach (Button elem in list) 
     { 
      text += elem.Content.ToString() + "\n"; 
     } 

     MessageBox.Show(text, "Text in Button"); 
    } 

一般有几种方式来访问模板。这里有一个:How to use FindName with a ContentControl