private void ExpandSingleProperties(PropertyViewItem item) { var node = GetNode(item); // The data context of the item might be a "disconnected object" if (node == null) { return; } var rule = GetRule(node); if (node.Parent != null) { switch (rule) { case ExpandRule.Always: // Always expand nodes that have this rule (without tracking them) item.SetCurrentValue(ExpandableItemsControl.IsExpandedProperty, true); break; case ExpandRule.Never: // Always collapse nodes that have this rule (without tracking them) item.SetCurrentValue(ExpandableItemsControl.IsExpandedProperty, false); break; case ExpandRule.Once: // Expand nodes that have this rule only if they have never been collapsed previously var propertyPath = GetNode(item).DisplayPath; if (!collapsedPropertyPaths.Contains(propertyPath)) { item.SetCurrentValue(ExpandableItemsControl.IsExpandedProperty, true); break; } goto default; default: // If the node is an only child, let's expand it if (node.Parent.Children.Count == 1) { item.SetCurrentValue(ExpandableItemsControl.IsExpandedProperty, true); // And keep a track of it, in case it has some siblings incoming expandedItems.Add(item); } else { // If one of its siblings has been expanded because it was an only child at the time it was created, let's unexpand it. // This will prevent to always have the first item expanded since the property items are generated as soon as a child is added. expandedItems.Where(x => GetNode(x).Parent == node.Parent).ForEach(x => x.SetCurrentValue(ExpandableItemsControl.IsExpandedProperty, false)); } break; } } foreach (var container in item.Properties) { ExpandSingleProperties(container); } }