2009-06-11 46 views
21

Hola, tengo pocos cuadros de texto dentro de la plantilla de datos para el control de elementos. Cuando enlace los controles de elementos a una colección observable, obtengo dos cuadros de texto. Pero tengo que hacer algunas manipulaciones basadas en cada uno de los cuadros de texto para los cuales quiero encontrar cada cuadro de texto por separado usando alguna identificación.Encontrar control dentro de WPF itemscontrol

¿Alguien puede ayudarme a encontrar un control en el control de elementos en WPF?

+1

Qué tipo de manipulación hacer necesitas actuar? ¿Necesita identificar los cuadros de texto de manera única entre todos los elementos del control de elementos o solo para separar los dos entre sí? – Oskar

+0

Hola Oscar Solo tenía etiquetas y cuadros de texto dentro de mis elementos de control. Necesito una forma de obtener el control del cuadro de texto de forma única (utilizando una identificación). La necesidad básica de establecer el foco en el cuadro de texto cuando se carga el control de elementos y necesita identificar cuál de los cuadros de texto tiene foco en un momento dado y realizar alguna operación. Gracias Deepak Gracias Deepak – deepak

+0

Más simplemente cómo puedo iterar sobre la colección de control de control de artículos usando C#. – deepak

Respuesta

62

Al usar ItemContainerGenerator puede obtener el contenedor generado para un elemento y recorrer el árbol visual hacia abajo para encontrar su TextBox. En el caso de un ItemsControl que será un ContentPresenter, pero un ListBox devolverá un ListBoxItem, ListView un ListViewItem, etc.

ContentPresenter cp = itemsControl.ItemContainerGenerator.ContainerFromItem(item) as ContentPresenter; 
TextBox tb = FindVisualChild<TextBox>(cp); 
if (tb != null) 
{ 
    // do something with tb 
} 

public static T FindVisualChild<T>(DependencyObject depObj) where T : DependencyObject 
{ 
    if (depObj != null) 
    { 
     for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) 
     { 
      DependencyObject child = VisualTreeHelper.GetChild(depObj, i); 
      if (child != null && child is T) 
      { 
       return (T)child; 
      } 

      T childItem = FindVisualChild<T>(child); 
      if (childItem != null) return childItem; 
     } 
    } 
    return null; 
} 

También puede obtener el contenedor por el índice si se desea usando

itemsControl.ItemContainerGenerator.ContainerFromIndex(0); 
+0

Muchas gracias Bryce – deepak

+0

¿Puedes marcar como la respuesta, por favor? –

+0

Estoy usando este método, pero lo estoy llamando en el constructor. (¿mala idea?) De todos modos, tuve que llamar a child.ApplyTemplate(); para que el árbol visual se llene para niños con plantillas definidas en recursos estáticos. –

2

Es posible que desee intentar usar VisualTreeHelper. Las propiedades de ItemsControl solo le permitirán obtener los datos a los que está vinculado, no las instancias de plantilla utilizadas para visualizar los datos, mientras que VisualTreeHelper le permite explorar el árbol visual tal como lo ha representado WPF.

Si itera por los elementos secundarios visuales de ItemControl padres (recursivamente), no debería tener ninguna dificultad para ubicar los cuadros de texto que está viendo en la pantalla.

5

Gracias Bryce, traté de marcar la flecha hacia arriba pero dice que mi calificación es demasiado baja. ¡Lo siento!

Modifiqué el código para devolver toda una lista de todos los hijos del tipo dado, ya que era lo que necesitaba y pensé que alguien más podría encontrarlo útil.

Gracias de nuevo Bryce, realmente útil: disculpa por la calificación!

public static List<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject 
    { 
     List<T> list = new List<T>(); 
     if (depObj != null) 
     { 
      for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) 
      { 
       DependencyObject child = VisualTreeHelper.GetChild(depObj, i); 
       if (child != null && child is T) 
       { 
        list.Add((T)child); 
       } 

       List<T> childItems = FindVisualChildren<T>(child); 
       if (childItems != null && childItems.Count() > 0) 
       { 
        foreach (var item in childItems) 
        { 
         list.Add(item); 
        } 
       } 
      } 
     } 
     return list; 
    } 
+0

Recientemente publiqué una pequeña variación de lo que está intentando hacer aquí: http://stackoverflow.com/questions/974598/find-all-controls-in-wpf-window-by-type –

+0

@Clarke: una solución menor - debería ser 'childItems.Count' en lugar de' childItems.Count() '. –

0

Si tiene cuadrícula de datos y la columna de la plantilla, que contiene la plantilla de datos, puede utilizar el siguiente ejemplo de código

<DataGridTemplateColumn x:Name="photoPathColumn" Header="{x:Static resx:FrmResource.Photo}"> 
    <DataGridTemplateColumn.CellEditingTemplate x:Uid="keyelm"> 
     <DataTemplate x:Name="dodo"> 
      <StackPanel Orientation="Horizontal" Height="Auto"> 
       <TextBlock x:Name="photo" x:Uid="imageFile" Text="{Binding Path=PhotoPath}" /> 
       <Button x:Name="Browse" Content="..." Click="Browse_Click" /> 
      </StackPanel> 
     </DataTemplate> 
    </DataGridTemplateColumn.CellEditingTemplate> 

photoPathColumn.CellEditingTemplate.FindName("photo",photoPathColumn.GetCellContent(CustomersDataGrid.CurrentItem)) 
1

Otro ejemplo:

private void DataGridBank_KeyUp(object sender, System.Windows.Input.KeyEventArgs e) 
    { 
     try 
     {  
      switch (e.Key) 
      { 
       case Key.Down: 

        if ((DataGridBank.SelectedIndex + 1) <= DataGridBank.Items.Count) 
        { 
         DataGridBank.SelectedIndex = DataGridBank.SelectedIndex + 1; 
         FocusCell(); 
        } 
        break; 

       case Key.Up: 

        if ((DataGridBank.SelectedIndex - 1) >= 0) 
        { 
         DataGridBank.SelectedIndex = DataGridBank.SelectedIndex - 1; 
         FocusCell(); 
        } 
        break; 

       case Key.Enter: 
       case Key.Tab: 
        FocusCell();     

        break; 
      } 
     } 
     catch (Exception ex) 
     { 

     } 
    } 


    private void DataGridBank_Loaded(object sender, RoutedEventArgs e) 
    { 
     try 
     { 
      if (DataGridBank.Items.Count > 0) 
      { 
       DataGridBank.SelectedIndex = 0; 

       FocusCell(); 
      } 

     }catch(Exception ex) 
     { 

     } 
    } 


    private void FocusCell() 
    { 
     var selectedRow = (DataGridRow)DataGridBank.ItemContainerGenerator.ContainerFromItem(DataGridBank.SelectedItem); 

     var textImport = FindVisualChild<TextBox>(selectedRow); 
     textImport.Focus(); 
     textImport.SelectAll(); 
    } 


    public static T FindVisualChild<T>(DependencyObject depObj) where T : DependencyObject 
    { 
     if (depObj != null) 
     { 
      for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) 
      { 
       DependencyObject child = VisualTreeHelper.GetChild(depObj, i); 
       if (child != null && child is T) 
       { 
        return (T)child; 
       } 

       T childItem = FindVisualChild<T>(child); 
       if (childItem != null) return childItem; 
      } 
     } 
     return null; 
    } 
Cuestiones relacionadas