所以,我希望用户能够自己构建一个树视图 树视图基本上包含两种项目:
MenuItem
继承TreeviewMenuItem
)MenuSubmenu
继承TreeviewMenuItem
,包含List<MenuItem>
) Treeview使用 ItemsSource ,这是List<TreeviewMenuItem>
。
用户可以将子菜单和项目添加到子菜单中 节点级别没有限制。
public abstract class TreeviewMenuItem
{
public virtual string Text { get; set; }
public virtual string DisplayName { get => Text; }
public virtual MenuSubmenu ParentMenu { get; set; } = null;
}
public class MenuSubmenu : TreeviewMenuItem
{
public override string DisplayName { get => Text + " [" + Items.Count + "]"; }
public List<MenuItem> Items { get; set; }
public MenuSubmenu(MenuSubmenu parent = null)
{
ParentMenu = parent;
Items = new List<MenuItem>();
}
}
public class MenuItem : TreeviewMenuItem
{
public MenuItem(MenuSubmenu parent = null)
{
ParentMenu = parent;
}
}
当用户构建完树视图后,它可以将其导出为XML 问题是:我如何遍历所有节点?
正如您所看到的,由于我的子菜单包含List<MenuItem>
,其中也可以包含子菜单(等),因此我无法通过ItemsSource使用简单的循环。
我不知道如何处理动态数量的子菜单及其包含的所有项目......
答案 0 :(得分:3)
要分析树,最简单的方法可能是编写递归方法。 像这样:
public void AnalyzeTree(List<TreeviewMenuItem> menuItems)
{
foreach (var menuItem in menuItems)
{
switch (menuItem)
{
case MenuSubmenu submenu:
// TODO: submenu action
AnalyzeTree(submenu.Items);
break;
case MenuItem item:
// TODO: item action
break;
}
}
}
答案 1 :(得分:1)
第一个问题,为什么需要迭代项目?只需获取树的基础并序列化它,XML序列化将处理所有子项。
为所有派生类添加XmlInclude
属性并使用XmlIgnore
省略循环非常重要
在你的例子中:
[XmlInclude(typeof(MenuSubmenu))]
[XmlInclude(typeof(MenuItem))]
public abstract class TreeviewMenuItem
{
public virtual string Text { get; set; }
public virtual string DisplayName { get => Text; }
[XmlIgnore]
public virtual MenuSubmenu ParentMenu { get; set; } = null;
}
public class MenuSubmenu : TreeviewMenuItem
{
public override string DisplayName { get => Text + " [" + Items.Count + "]"; }
[XmlArrayItem(Type = typeof(TreeviewMenuItem)),
XmlArrayItem(Type = typeof(MenuSubmenu))]
public List<MenuItem> Items { get; set; }
public MenuSubmenu(MenuSubmenu parent = null)
{
Items = new List<MenuItem>();
}
}
public class MenuItem : TreeviewMenuItem
{
public MenuItem(MenuSubmenu parent = null)
{
ParentMenu = parent;
}
}