webentwicklung-frage-antwort-db.com.de

Kontrolle in WPF itemscontrol finden

Hallo, ich habe nur ein einziges Textfeld in der Datenvorlage für itemscontrol. Wenn ich die Itemcontrols an eine beobachtbare Sammlung binde, erhalte ich zwei Textfelder. Aber ich muss einige Manipulationen vornehmen, die auf jedem der Textfelder basieren, für die ich jedes Textfeld einzeln mit einer ID finden möchte.

Kann jemand helfen, wie man ein Steuerelement in der Itemscontrol in WPF findet.

22
deepak

Mit dem ItemContainerGenerator können Sie den generierten Container für ein Element abrufen und den visuellen Baum nach unten durchlaufen, um Ihre TextBox zu finden. Bei einem ItemsControl ist es ein ContentPresenter, aber eine ListBox gibt ein ListBoxItem, ListView ein ListViewItem usw. zurück.

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

Sie können den Container auch nach Index abrufen, indem Sie verwenden

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

Danke Bryce, ich habe versucht, den Aufwärtspfeil anzukreuzen, aber es heißt, meine Bewertung ist zu niedrig! Es tut uns leid!

Ich habe den Code geändert, um eine Liste aller Kinder des angegebenen Typs zurückzugeben, da dies das war, was ich brauchte, und dachte, jemand anderes könnte es nützlich finden.

Nochmals vielen Dank, Bryce, sehr hilfreich - Entschuldigung für die Bewertung!

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

Möglicherweise möchten Sie versuchen, VisualTreeHelper zu verwenden. Mit den Eigenschaften von ItemsControl selbst können Sie nur die Daten ermitteln, an die es gebunden ist, und nicht die Vorlageninstanzen, die zum Visualisieren der Daten verwendet werden. Mit VisualTreeHelper können Sie den visuellen Baum durchsuchen, während WPF ihn gerendert hat.

Wenn Sie die visuellen untergeordneten Elemente des übergeordneten Elements (rekursiv) durchlaufen, sollten Sie keine Schwierigkeiten haben, die auf dem Bildschirm angezeigten Textfelder zu finden.

2

Ein anderes Beispiel:

    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

Wenn Sie über ein Datenraster und eine Vorlagenspalte verfügen, die eine Datenvorlage enthält, können Sie das folgende Codebeispiel verwenden

<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