添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

Hi i have few a single textbox within the the datatemplate for itemscontrol. When i bind the itemcontrols to a observable collection i get two text boxes. But i need to do some manipulations based on each of the text boxes for which i want to find each textbox seperatly using some id.

Can anybody help on how to find a control witin the itemscontrol in WPF.

What kind of manipulation do you need to perform? Do you need to identify the textboxes uniquely among all items of the itemscontrol or only to separate the two from each other? Oskar Jun 11, 2009 at 10:54 Hi Oscar I had only labels and textboxes inside my itemscontrol. I need a way to get the handle for textbox control uniquely (using some id). The basic need to set focus on textbox when the itemscontrol is loaded and need to identify which of the textboxes has focus at a given time and perform some operation. Thanks Deepak Thanks Deepak deepak Jun 11, 2009 at 11:21

Using the ItemContainerGenerator you can obtain the generated container for an item and traverse the visual tree downwards to find your TextBox. In the case of an ItemsControl it will be a ContentPresenter, but a ListBox will return a ListBoxItem, ListView a 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;

You can also obtain the container by index if you want by using

itemsControl.ItemContainerGenerator.ContainerFromIndex(0);
                I'm using this method, but I'm calling it in the constructor.  (bad idea?)  Anyhow, I had to call child.ApplyTemplate(); to get the visual tree to populate for children with templates defined in static resources.
– Matt Becker
                May 7, 2014 at 15:22

Thanks Bryce, I tried to tick the up arrow but it says my rating is too low! Sorry!

I amended the code to return all a list of all the children of the given type as it was what I needed and thought someone else might find it useful.

Thanks again Bryce, really helpful - sorry about the rating thing!

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;
                I recently posted a slight variation of what you are trying to do here: stackoverflow.com/questions/974598/…
– Bryce Kahle
                Jun 27, 2009 at 1:22

You may want to try using VisualTreeHelper. The properties on ItemsControl itself will only allow you to get the data its bound to, not the template instances used to visualize the data, while VisualTreeHelper allows you to browse around the visual tree as WPF has rendered it.

If you iterate through the parent ItemControl's visual children (recursively), you shouldn't have any difficulty locating the text boxes you are seeing on screen.

Another example:

    private void DataGridBank_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
            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)
            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;

If you have data grid and template column, which contains data template, you can use the following code sample

<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)) 
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.