我有一个名为GetMenuItems的方法,它返回Heirarchical结果。以下是实施:
public static ObservableCollection<MenuItem> GetMenuItems()
{
XDocument xDoc = XDocument.Load(DirectoryPaths.DataDirectory_General + "MenuItems.xml");
return LoadMenuItems(xDoc.Descendants("MenuItem"));
}
private static ObservableCollection<MenuItem> LoadMenuItems(IEnumerable<XElement> menuItems)
{
return new ObservableCollection<MenuItem>(
menuItems.Select(
x => new MenuItem()
{
Id = Convert.ToDouble(x.Attribute("Id").Value),
Name = x.Element("Name").Value,
ImageData = x.Elements("ImageData").Any() ? x.Element("ImageData").Value : "",
Angle = x.Elements("Angle").Any() ? Convert.ToDouble(x.Element("Angle").Value) : 0,
ScaleX = x.Elements("ScaleX").Any() ? Convert.ToInt32(x.Element("ScaleX").Value) : 0,
ScaleY = x.Elements("ScaleY").Any() ? Convert.ToInt32(x.Element("ScaleY").Value) : 0,
ShortcutKey = x.Elements("ShortcutKey").Any() ? x.Element("ShortcutKey").Value : "",
Background = x.Elements("Background").Any() ? x.Element("Background").Value : "#FF000000",
MouseOver = x.Elements("MouseOver").Any() ? x.Element("MouseOver").Value : "#FF696969",
menuItem = x.Elements("MenuItem").Any() ? LoadMenuItems(x.Elements("MenuItem")) : null
}
)
);
}
现在我想得到特定父母的所有直接子女。
为了更清楚,让我举一个例子:
假设我想得到Id = 1
的所有MenuItem的直接子MenuItem。
请注意,我需要使用GetMenuItems()方法,因为我不允许访问这些XML文件。
答案 0 :(得分:2)
您应该将任务分为两部分:
后者很简单 - 您只需使用menuItem
属性,该属性更好地命名为Children
或类似的东西。
我通过递归来解决第一部分 - 在做出一个重要的改变之后。如果没有元素,则Children
属性为null,而不是让它成为空集合:
Children = LoadMenuItems(x.Elements("MenuItem")
这样,即使没有任何孩子,你也可以很容易地检查所有孩子 - 没有任何无效检查。通常,将缺少项目表示为空集合而不是空引用更容易。
因此,要按ID递归查找菜单项,我会使用:
// TODO: Change the ID type from double to almost anything else. double is a
// *terrible* type to use for IDs.
public MenuItem FindMenuItemById(MenuItem item, double id)
{
return item.Id == id ? item : item.Children
.Select(x => FindMenuItemById(x, id))
.Where(found => found != null)
.FirstOrDefault();
}
如果没有这样的菜单项,那将返回null
。然后你可以使用:
if (item != null)
{
var children = item.Children;
...
}
另外,使用XElement
上的转换运算符和空合并运算符
// Again, change this! Don't use double!
Id = (double) x.Attribute("Id"),
Name = (string) x.Element("Name"),
ImageData = (string) x.Element("ImageData") ?? "",
Angle = (double?) x.Element("Angle") ?? 0d,
ScaleX = (double?) x.Element("ScaleX") ?? 0d,
ScaleY = (double?) x.Element("ScaleY") ?? 0d,
ShortcutKey = (string) x.Element("ShortcutKey") ?? "",
Background = (string) x.Element("Background") ?? "#FF000000",
MouseOver = (string) x.Element("MouseOver") ?? "#FF696969",