简体   繁体   English

在C#中访问嵌套的XAML控件

[英]Accessing a nested XAML control within C#

I'm creating an application whereby there is a TextBox element within a DataTemplate, within a ListBox in WPF. 我正在创建一个应用程序,其中WPF中的ListBox内的DataTemplate内有一个TextBox元素。 I want to access the TextBox element by name in order to edit, or read the value directly from C# code, please help. 我想按名称访问TextBox元素以进行编辑,或直接从C#代码中读取值,请帮忙。 There are multiple TextBoxes added within the WPF application, so how may I sort these out by index as well? WPF应用程序中添加了多个TextBoxes,那么如何按索引对它们进行排序呢?

<ListBox x:Name="listBox" HorizontalAlignment="Left" Height="336" Margin="276,69,0,0" VerticalAlignment="Top" Width="242" SelectionChanged="listBox_SelectionChanged">
        Grid.IsSharedSizeScope="True"
        HorizontalContentAlignment="Stretch">
        <ListBox.ItemTemplate>
            <DataTemplate x:Name="D_Template">
                <Grid Margin="4" Width="222">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" SharedSizeGroup="Key" />
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                    <TextBox x:Name ="TextValue" Grid.Column="1" Text="{Binding Value}" />
                </Grid>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

As you can see, the ListBox has the variable name "listBox", the DataTemplate has been assigned to "D_Template" and the TextBox is assigned to the name "TextValue". 如您所见,ListBox具有变量名称“ listBox”,DataTemplate已分配给“ D_Template”,而TextBox被分配给了名称“ TextValue”。 Any help is appreciated, thank you for your time. 感谢您的帮助,感谢您的宝贵时间。 :) :)

You should really bind the listbox itemssource to a collection of objects and read/change it instead of access directly to the textbox.But if for some reason you can't or don't want to do that, this code could help you. 您应该真正将列表框项目源绑定到对象集合并读取/更改它,而不是直接访问文本框。但是如果由于某种原因您不愿意或不想这样做,此代码可以为您提供帮助。 (Please note that I really discourage this solution) (请注意,我真的不鼓励这种解决方案)

    private void Button_Click(object sender, RoutedEventArgs e)
    {   //pretend you want to access the second item
        object myItem = myListbox.Items[1];
        ListBoxItem container = myListbox.ItemContainerGenerator.ContainerFromItem(myItem) as ListBoxItem;
        ContentPresenter contentPresenter = FindVisualChild<ContentPresenter>(container);
        DataTemplate myDataTemplate = contentPresenter.ContentTemplate;
        TextBox myTextbox = myDataTemplate.FindName("myTextbox", contentPresenter)as TextBox;
        if (myTextbox != null)
        {
            myTextbox.Text = "text changed!";
        }
    }

    public static IEnumerable<T> FindVisualChildren<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)
                {
                    yield return (T)child;
                }

                foreach (T childOfChild in FindVisualChildren<T>(child))
                {
                    yield return childOfChild;
                }
            }
        }
    }

    public static childItem FindVisualChild<childItem>(DependencyObject obj)
        where childItem : DependencyObject
    {
        foreach (childItem child in FindVisualChildren<childItem>(obj))
        {
            return child;
        }

        return null;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM