web-dev-qa-db-fra.com

Recherche du contrôle dans WPC itemscontrol

Salut, j'ai peu d'une seule zone de texte dans le datatemplate pour itemscontrol. Lorsque je lie les contrôles d’article à une collection observable, j’obtiens deux zones de texte. Mais je dois faire quelques manipulations basées sur chacune des zones de texte pour lesquelles je veux trouver chaque zone de texte séparément en utilisant un identifiant.

Quelqu'un peut-il aider à trouver un contrôle dans le contrôle des éléments dans WPF.

22
deepak

À l'aide de ItemContainerGenerator, vous pouvez obtenir le conteneur généré pour un élément et parcourir l'arborescence visuelle vers le bas pour trouver votre zone de texte. Dans le cas d'un ItemsControl, ce sera un ContentPresenter, mais un ListBox retournera 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;
}

Vous pouvez également obtenir le conteneur par index si vous le souhaitez en utilisant

itemsControl.ItemContainerGenerator.ContainerFromIndex(0);
65
Bryce Kahle

Merci Bryce, j'ai essayé de cocher la flèche vers le haut mais cela dit que ma note est trop basse! Pardon!

J'ai modifié le code pour renvoyer à tous une liste de tous les enfants du type donné, car c'était ce dont j'avais besoin et j'ai pensé que quelqu'un d'autre pourrait le trouver utile.

Merci encore Bryce, vraiment utile - désolé pour l'évaluation!

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;
    }
5
Andy Clarke

Vous voudrez peut-être essayer d’utiliser VisualTreeHelper . Les propriétés de ItemsControl lui-même ne vous permettront d'obtenir que les données auxquelles elles sont liées, pas les instances de modèles utilisées pour visualiser les données, alors que VisualTreeHelper vous permet de parcourir l'arborescence visuelle telle que WPF l'a restituée.

Si vous parcourez (de manière récursive) les enfants visuels de ItemControl du parent, vous ne devriez pas avoir de difficulté à localiser les zones de texte que vous voyez à l'écran.

2
Nicholas Armstrong

Un autre exemple:

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

Si vous avez une grille de données et une colonne de modèle, qui contient un modèle de données, , Vous pouvez utiliser l'exemple de code suivant.

<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)) 
0
Mohamed Abdo