【问题标题】:WPF - Retrieve Child DataTemplate Control From Custom ListBoxItemWPF - 从自定义 ListBoxItem 检索子 DataTemplate 控件
【发布时间】:2013-12-29 06:47:43
【问题描述】:

在我的应用程序中,我有一个带有自定义 DataTemplate 的 ListBox。 XAML 如下:

<ListBox Name="lstTasks">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal" VerticalAlignment="Top">
                <CheckBox Name="chkIsChecked" VerticalAlignment="Top" IsChecked="{Binding Path=IsChecked, Mode=TwoWay}"/>
                <RichTextBox Name="rtbTask" HorizontalAlignment="Left" Height="50" VerticalAlignment="Top" Width="450"
                             BorderBrush="{DynamicResource {x:Static SystemColors.ActiveCaptionTextBrushKey}}" Margin="0,0,0,10"/>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

我使用一个名为 CheckBoxItem 的自定义类作为我的 ListBoxItems。如果我想向 ListBox 添加一个项目,我将使用以下代码作为示例:

lstTasks.Items.Add(new CheckBoxItem("", false));

如果我想从 ListBox 中检索此项目,我将使用以下代码:

CheckBoxItem CheckBoxItem = (CheckBoxItem)lstTasks.Items[0];

我对数据绑定没有问题;它工作正常。我的问题是检索 DataTemplate 中的一个孩子。在应用程序中,用户可以在每个 CheckBoxItem 内编辑 RichTextBox 的内容。我希望能够将 RichTextBox 的内容保存到外部文件中。我已经创建了获取 RTF 文本并将其存储在字符串中的方法,但我似乎无法访问任何给定 CheckBoxItem 的 RichTextBox。

我在网上搜索了很长时间,但似乎找不到任何有用的东西。使用 VisualTree 不起作用,因为 CheckBoxItems 不是 DependencyObjects 并且不能转换为它们。结果,我很困惑,非常感谢您对此问题的任何见解。

我的一个想法是跟踪某种集合中的所有 RichTextBox。我会处理他们的 Loaded 事件,然后将它们添加到那里的集合中,但我真的不想这样做,因为这似乎是对内存的不必要使用。

提前感谢您的帮助!

【问题讨论】:

    标签: wpf class listbox datatemplate listboxitem


    【解决方案1】:

    没有简单的方法。但是知道您之前已经遇到过VisualTree 的东西,也许您已经看过以下示例中的大部分代码。您可能错过的是第一行,它向您展示了如何从CheckBoxItem 获取ListBoxItem。手头有ListBoxItem,意味着您有一个DependencyObject 可以开始使用VisualTree 东西技术来查找RichTextBox

    var myListBoxItem = (lstTasks.ItemContainerGenerator.ContainerFromItem(lstTasks.Items[0]));
    
    // Getting the ContentPresenter of myListBoxItem
    ContentPresenter myContentPresenter = FindVisualChild<ContentPresenter>(myListBoxItem);
    
    // Finding richtextbox from the DataTemplate that is set on that ContentPresenter
    DataTemplate myDataTemplate = myContentPresenter.ContentTemplate;
    RichTextBox myTextBlock = (RichTextBox)myDataTemplate.FindName("rtbTask", myContentPresenter);
    

    FindVisualChild 的实现如MSDN 所示:

    private childItem FindVisualChild<childItem>(DependencyObject obj) where childItem : DependencyObject
    {
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
        {
            DependencyObject child = VisualTreeHelper.GetChild(obj, i);
            if (child != null && child is childItem)
                return (childItem)child;
            else
            {
                childItem childOfChild = FindVisualChild<childItem>(child);
                if (childOfChild != null)
                    return childOfChild;
            }
        }
        return null;
    }
    

    【讨论】:

    • 非常感谢;效果很棒!我找到了 MSDN 示例,但已将第一行更改为 CheckListItem 类型。这一次,我将 myListBoxItem 声明为 ListBoxItem,然后将 ContainerFromItem 方法转换为 ListBoxItem。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 2018-01-11
    • 1970-01-01
    • 2010-12-10
    • 1970-01-01
    • 2016-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多