Нахождение контроля в WPF itemscontrol - PullRequest
22 голосов
/ 11 июня 2009

Привет, у меня есть несколько текстовых полей в табличке с данными для itemscontrol. Когда я связываю элемент управления элемента с наблюдаемой коллекцией, я получаю два текстовых поля. Но мне нужно сделать некоторые манипуляции, основанные на каждом из текстовых полей, для которых я хочу найти каждое текстовое поле отдельно, используя некоторый идентификатор.

Может кто-нибудь помочь с тем, как найти элемент управления с помощью элемента управления в WPF.

Ответы [ 5 ]

67 голосов
/ 12 июня 2009

Используя ItemContainerGenerator, вы можете получить сгенерированный контейнер для элемента и пройти по визуальному дереву вниз, чтобы найти ваш TextBox. В случае ItemsControl это будет ContentPresenter, но ListBox вернет ListBoxItem, ListView a ListViewItem и т. Д.

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;
}

Вы также можете получить контейнер по индексу, если хотите, используя

itemsControl.ItemContainerGenerator.ContainerFromIndex(0);
5 голосов
/ 25 июня 2009

Спасибо, Брайс, я пытался пометить стрелку вверх, но там написано, что мой рейтинг слишком низкий! Извините!

Я исправил код, чтобы он возвращал весь список всех потомков данного типа, поскольку это было то, что мне было нужно, и подумал, что кто-то еще может найти его полезным.

Еще раз спасибо, Брайс, очень полезно - извините за оценку!

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;
    }
2 голосов
/ 11 июня 2009

Возможно, вы захотите попробовать VisualTreeHelper . Свойства самого ItemsControl позволят вам получать только те данные, с которыми он связан, а не экземпляры шаблона, используемые для визуализации данных, в то время как VisualTreeHelper позволяет просматривать дерево визуалов, как его визуализировал WPF.

Если вы перебираете визуальные дочерние элементы родительского ItemControl (рекурсивно), у вас не должно возникнуть проблем с поиском текстовых полей, которые вы видите на экране.

1 голос
/ 08 ноября 2012

Другой пример:

    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;
    }
0 голосов
/ 17 августа 2010

Если у вас есть сетка данных и столбец шаблона, который содержит шаблон данных, Вы можете использовать следующий пример кода

<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)) 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...