C# 在树状视图中删除具有自底向上删除的子级的最佳循环?

C# 在树状视图中删除具有自底向上删除的子级的最佳循环?,c#,wpf,treeview,C#,Wpf,Treeview,我有一个树状视图,组织如下: Level1 level 1.1 level 1.1.1 level 1.1.2 level 1.1.3 level 1.1.3.1 level 1.1.3.2 level 1.2 level 1.3 level2 level 2.1 ............. 每个级别都是从TreeViewModelBase继承的ViewModel 给定一个级别为1.1.3.2的viewmod

我有一个树状视图,组织如下:

Level1
   level 1.1
     level 1.1.1
     level 1.1.2
     level 1.1.3
       level 1.1.3.1
       level 1.1.3.2
   level 1.2
   level 1.3
level2
   level 2.1

 .............
每个级别都是从TreeViewModelBase继承的ViewModel

给定一个级别为1.1.3.2的viewmodel,此代码将从树视图中删除它:

var y = SelectedItem as TreeViewModelBase;
var z = y.Parent;

z.Children.Remove(y);

if (z.Children.Count == 0)
{
    var g = z.Parent;
    g.Children.Remove(z);
} 
从选定项开始并将其从其父项中移除的单个循环是什么。如果父级不再具有任何子级,则将父级从父级中移除,并同样建立树结构

最好的循环构造是什么


谢谢您的帮助。

以下是我的想法:

  • 可以使用友好语法构造的项模型(无需设置其父项)
  • 一个修剪工具,将删除一个项目,并尽可能多地清理层次结构
例子 (删减项目1.4.1.1)

之前:

之后:

物体:
项目
:您的项目

  • 它监视您添加到其中的孩子,并(取消)设置其
    Parent
    属性
  • 提供了
    Prune
    方法,可将其从其父对象中移除,向上爬升并重复,直到不可能
代码:

演示代码

public partial class MainWindow
{
    public MainWindow()
    {
        InitializeComponent();
        Loaded += MainWindow_Loaded;
    }

    private void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        var root = new Item
        {
            Name = "root",
            Children = new ItemCollection(new[]
            {
                new Item
                {
                    Name = "item1.1",
                    Children = new ItemCollection(new[]
                    {
                        new Item {Name = "item1.1.1"},
                        new Item {Name = "item1.1.2"}
                    })
                },
                new Item
                {
                    Name = "item1.2",
                    Children = new ItemCollection(new[]
                    {
                        new Item {Name = "item1.2.1"}
                    })
                },
                new Item {Name = "item1.3"}
            })
        };

        var item1411 = new Item
        {
            Name = "item1.4.1.1"
        };
        var item141 = new Item
        {
            Name = "item1.4.1",
            Children = new ItemCollection(new[]
            {
                item1411
            })
        };
        var item14 = new Item
        {
            Name = "item1.4",
            Children = new ItemCollection(new[]
            {
                item141
            })
        };
        root.Children.Add(item14);

        Console.WriteLine("-----------------");
        Console.WriteLine("before pruning");
        Console.WriteLine("-----------------");
        PrintHierarchy(root);

        Console.WriteLine("-----------------");
        Console.WriteLine("after pruning");
        Console.WriteLine("-----------------");
        item1411.Prune();
        PrintHierarchy(root);

        DataContext = root;
    }

    private void PrintHierarchy(Item root, int level = 0)
    {
        Console.WriteLine("{0}{1}", string.Concat(Enumerable.Repeat(" ", level)), root);

        if (root.Children.Count > 0)
        {
            foreach (Item child in root.Children)
            {
                PrintHierarchy(child, level + 1);
            }
        }
    }
}
XAML:


树视图将无缝更新。

我同意Aybe的回答。在我的特定案例中,所有ViewModel都保存在ObservableCollections中,并且都来自同一个TreeViewModelBase,下面的代码似乎更简单。树视图将自动更新

  var z = SelectedItem as TreeViewModelBase;

   TreeViewModelBase y;
                        do
                        {
                            y = z;

                            if (y.Parent == null) break;
                            z = y.Parent;
                            z.Children.Remove(y);

                        } while(z.Children.Count==0);
public partial class MainWindow
{
    public MainWindow()
    {
        InitializeComponent();
        Loaded += MainWindow_Loaded;
    }

    private void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        var root = new Item
        {
            Name = "root",
            Children = new ItemCollection(new[]
            {
                new Item
                {
                    Name = "item1.1",
                    Children = new ItemCollection(new[]
                    {
                        new Item {Name = "item1.1.1"},
                        new Item {Name = "item1.1.2"}
                    })
                },
                new Item
                {
                    Name = "item1.2",
                    Children = new ItemCollection(new[]
                    {
                        new Item {Name = "item1.2.1"}
                    })
                },
                new Item {Name = "item1.3"}
            })
        };

        var item1411 = new Item
        {
            Name = "item1.4.1.1"
        };
        var item141 = new Item
        {
            Name = "item1.4.1",
            Children = new ItemCollection(new[]
            {
                item1411
            })
        };
        var item14 = new Item
        {
            Name = "item1.4",
            Children = new ItemCollection(new[]
            {
                item141
            })
        };
        root.Children.Add(item14);

        Console.WriteLine("-----------------");
        Console.WriteLine("before pruning");
        Console.WriteLine("-----------------");
        PrintHierarchy(root);

        Console.WriteLine("-----------------");
        Console.WriteLine("after pruning");
        Console.WriteLine("-----------------");
        item1411.Prune();
        PrintHierarchy(root);

        DataContext = root;
    }

    private void PrintHierarchy(Item root, int level = 0)
    {
        Console.WriteLine("{0}{1}", string.Concat(Enumerable.Repeat(" ", level)), root);

        if (root.Children.Count > 0)
        {
            foreach (Item child in root.Children)
            {
                PrintHierarchy(child, level + 1);
            }
        }
    }
}
<Window x:Class="WpfApplication3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:wpfApplication3="clr-namespace:WpfApplication3"
        Title="MainWindow"
        Width="525"
        Height="350">
    <Grid>
        <Grid.Resources>
            <Style TargetType="TreeViewItem">
                <Setter Property="IsExpanded" Value="True" />
            </Style>
        </Grid.Resources>
        <TreeView ItemsSource="{Binding (wpfApplication3:Item.Children)}">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate DataType="wpfApplication3:Item" ItemsSource="{Binding Children}">
                    <HierarchicalDataTemplate.ItemTemplate>
                        <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                            <TextBlock Text="{Binding Name}" />
                        </HierarchicalDataTemplate>
                    </HierarchicalDataTemplate.ItemTemplate>
                    <TextBlock Text="{Binding Name}" />
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>
    </Grid>
</Window>
private void Button_Click(object sender, RoutedEventArgs e)
{
    _item1411.Prune();
}
  var z = SelectedItem as TreeViewModelBase;

   TreeViewModelBase y;
                        do
                        {
                            y = z;

                            if (y.Parent == null) break;
                            z = y.Parent;
                            z.Children.Remove(y);

                        } while(z.Children.Count==0);