public static Dictionary <string, TreeItem> PopulatePropertyTree( IEnumerable <PropertyConfig> properties, ObservableCollection <TreeItem> treeItems, bool isInstalled, Action <TreeItem, PropertyConfig> OnCreate = null) { Dictionary <string, TreeItem> dict = new Dictionary <string, TreeItem>(); // Build tree based on property names foreach (var p in properties) { var treeItem = AddTreeItem(dict, treeItems, p); OnCreate?.Invoke(treeItem, p); } // Populating installed tree - do some surgery on the system properties if (isInstalled) { List <TreeItem> roots = new List <TreeItem>(treeItems); treeItems.Clear(); List <TreeItem> lastRoots = new List <TreeItem>(); // Wire trees to tree controls, tweaking the structure as we go TreeItem propGroup = null; foreach (TreeItem root in roots) { if (root.Name == "System") { lastRoots.Insert(0, root); // Move property groups from root to their own subtree propGroup = root.Children.Where(x => x.Name == "PropGroup").FirstOrDefault(); if (propGroup != null) { root.RemoveChild(propGroup); lastRoots.Add(propGroup); } // Move properties with names of the form System.* to their own subtree var systemProps = new TreeItem("System.*"); lastRoots.Insert(0, systemProps); foreach (var ti in root.Children.Where(x => x.Children.Count == 0).ToList()) { root.RemoveChild(ti); systemProps.AddChild(ti); } } else if (root.Name == "Microsoft") { lastRoots.Insert(0, root); } else { treeItems.Add(root); } } foreach (var ti in lastRoots) { treeItems.Add(ti); } } else { // Fully expand the saved tree ExpandTree(treeItems); } return(dict); }