【问题标题】:Accessing a nested XAML control within C#在 C# 中访问嵌套的 XAML 控件
【发布时间】:2016-07-17 17:46:52
【问题描述】:

我正在创建一个应用程序,其中在 WPF 的 ListBox 中的 DataTemplate 中有一个 TextBox 元素。我想按名称访问 TextBox 元素以进行编辑,或直接从 C# 代码中读取值,请帮助。 WPF 应用程序中添加了多个 TextBox,那么如何按索引对它们进行排序呢?

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

如您所见,ListBox 具有变量名称“listBox”,DataTemplate 已分配给“D_Template”,TextBox 已分配给名称“TextValue”。任何帮助表示赞赏,感谢您的时间。 :)

【问题讨论】:

  • 如果您想从 Code Behind 访问它,x:Name 属性应该可以正常工作。
  • 感谢您的回复!
  • 不,您需要提供一个良好的minimal reproducible example,准确显示您正在尝试做什么。在几乎所有情况下,直接访问 UI 元素都是错误的做法。您需要访问的值应该绑定到某个视图模型对象,您可以使用它来检索该值。在您的示例中,这意味着您的 ListBox 显示了绑定到模板的视图模型对象的集合,其中视图模型属性(或属性)绑定到您要访问的 TextBox 属性(属性) .请提供更清晰的代码示例,并准确描述您要执行的操作。
  • @Fang:使用Namex:Name 只会在代码隐藏中为代码隐藏对象的XAML 中声明的实际元素生成一个字段(例如Window)。通过模板实例化的项目不这样做。他们的名字仍然可以在他们自己的上下文/范围内访问,但不能作为代码隐藏中的字段。
  • @PeterDuniho:谢谢彼得。

标签: c# wpf xaml listbox


【解决方案1】:

您应该真正将列表框项目源绑定到对象集合并读取/更改它,而不是直接访问文本框。但是如果由于某种原因您不能或不想这样做,此代码可能会有所帮助你。 (请注意,我真的不鼓励这种解决方案)

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

【讨论】:

  • 谢谢!我会认真考虑你告诉我的。 - CR
猜你喜欢
  • 1970-01-01
  • 2021-10-16
  • 1970-01-01
  • 2011-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-21
  • 1970-01-01
相关资源
最近更新 更多