Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 如何在标记属性中找到具有特定值的TreeViewItem_.net_Wpf_Treeview_Treeviewitem - Fatal编程技术网

.net 如何在标记属性中找到具有特定值的TreeViewItem

.net 如何在标记属性中找到具有特定值的TreeViewItem,.net,wpf,treeview,treeviewitem,.net,Wpf,Treeview,Treeviewitem,我正在尝试查找一个特定的treevieItem,它的标记属性设置为特定值。下面的FindNode仅适用于第一级项目,如果父级TreeViewItem展开,则在其他级别中也适用。在下面的示例中,如果展开“FFF”,则FindNode将按预期工作。我假设ContainerFromItem返回null,因为这些项尚未创建。有没有办法强制创建所有的树元素 <TreeView x:Name="__items"> <TreeViewItem Header="AAA

我正在尝试查找一个特定的
treevieItem
,它的
标记
属性设置为特定值。下面的
FindNode
仅适用于第一级项目,如果父级
TreeViewItem
展开,则在其他级别中也适用。在下面的示例中,如果展开“FFF”,则
FindNode
将按预期工作。我假设
ContainerFromItem
返回null,因为这些项尚未创建。有没有办法强制创建所有的树元素

    <TreeView x:Name="__items">

        <TreeViewItem Header="AAA"
                      Tag="{x:Static my:Node.A}" />

        <TreeViewItem Header="BBB"
                      Tag="{x:Static my:Node.B}">

            <!-- Items will be added later. -->

        </TreeViewItem>

        <TreeViewItem Header="CCC"
                      Tag="{x:Static my:Node.C}" />

        <TreeViewItem Header="DDD"
                      Tag="{x:Static my:Node.D}" />

        <TreeViewItem Header="EEE"
                      Tag="{x:Static my:Node.E}" />

        <TreeViewItem Header="FFF"
                      Tag="{x:Static my:Node.F}">

            <TreeViewItem Header="GGG"
                          Tag="{x:Static my:Node.G}" />

            <TreeViewItem Header="HHH"
                          Tag="{x:Static my:Node.H}" />

        </TreeViewItem>

        <TreeViewItem Header="III"
                      Tag="{x:Static my:Node.I}" />

    </TreeView>

根据hbarck的回答,正确的
FindNode
实现为:

    private TreeViewItem FindNode(ItemCollection items, Node value)
    {
        TreeViewItem oResult = null;

        foreach (var oItem in items)
        {
            TreeViewItem oTreeViewItem = (TreeViewItem)oItem;

            if ((Node)oTreeViewItem.Tag == value) { oResult = oTreeViewItem; break; }

            if (oTreeViewItem.Items.Count > 0)
            {
                oResult = FindNode(oTreeViewItem.Items, value);

                if (oResult != null) { break; }
            }
        }
        return oResult;
    }

是,您可以强制在ItemsControl中创建项。 访问ItemContainerGenerator,然后(这是魔术;))将其强制转换为IItemContainerGenerator,因为接口是显式实现的。 使用StartAt和GenerateNext可以强制创建项

见:
您只需对所有项目执行此操作。

确保您的TreeView项目存在的最简单方法可能是在每个项目上设置IsExpanded=“True”,并在TreeView上将IsVirtualization设置为False。出于好奇:如果不使用ItemGenerator,而是直接迭代Items集合,会发生什么?由于您没有使用DataTemplate,我认为Items集合应该包含XAML文件中的硬编码项

我做了以下测试:

<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
    <TreeView x:Name="TestTreeView">
        <TreeViewItem Header="Item 1">
            <TreeViewItem Header="Item 1 1"/>
            <TreeViewItem Header="Item 1 2"/>
        </TreeViewItem>
        <TreeViewItem Header="Item 2"/>
    </TreeView>
    <Button x:Name="TestButton" Click="TestButton_Click">Test</Button>
</StackPanel>
</Window>
调试窗口中的输出为

Item: Item 1, Child count:2
Item: Item 2, Child count:0

这意味着项目是实例化的,并且可以迭代,即使在子级中也是如此。可能会影响您的是ItemContainerGenerator,实际上只有在使用DataTemplates时才需要它。此外,您可能必须等到窗口的Loaded事件之后,才能实例化所有项目。

我无法修改代码以开始工作。你能提供一个例子吗?这里你有一个完整的例子如何强制创建项目:太复杂了。这不会那么难。如果你想强制创建项目,那就是办法,对不起。你不使用MVVM模式有什么特别的原因吗?WPFStreeview与MVVM一起使用时效果非常好。以另一种方式使用它可能非常难看,给你一种感觉‘这太难了,我可能做错了什么’。当您发现一个带有特定标记的TreeViewItem时,您打算在代码中做什么?我继承的遗留代码。我正试图理顺spagetti,以便使代码库成形,以便接受视图模型。(目前,存在多个视图模型和代码隐藏的混合。)我需要查找项目,因为它们当前在quote/un quote view-model中硬编码。无论项目生成器如何,我都可以迭代第一级项目。现在我正在使用“IsExpanded=True”进入其他级别。IsVirtualization=False没有任何区别。我已经更新了我的答案,以表明可以迭代这些项及其子项,因为这些项是硬编码的。
Class MainWindow 

    Private Sub TestButton_Click(sender As System.Object, e As System.Windows.RoutedEventArgs)

        Stop
        For Each t As TreeViewItem In Me.TestTreeView.Items
            Debug.Print("Item: {0}, Child count:{1}", t.Header, t.Items.Count)
        Next
    End Sub
End Class
Item: Item 1, Child count:2
Item: Item 2, Child count:0