// <summary> // Creates an instance of SelectionPath to the specified category container's // basic or advanced sections that this class knows how to interpret. // </summary> // <param name="categoryName">Name of the category</param> // <param name="isAdvanced">True if the path should lead to the advanced section, // false otherwise.</param> // <returns>A new instance of SelectionPath to the specified section of the specified // category container.</returns> public SelectionPath ConstructSelectionPath(string categoryName, bool isAdvanced) { StringBuilder path = new StringBuilder(PersistedStateUtilities.Escape(categoryName)); if (isAdvanced) { path.Append(",Advanced"); } return(new SelectionPath(PathTypeId, path.ToString())); }
// ISelectionPathInterpreter Members public DependencyObject ResolveSelectionPath(CategoryList root, SelectionPath path, out bool pendingGeneration) { pendingGeneration = false; if (path == null || !string.Equals(PathTypeId, path.PathTypeId)) { Debug.Fail("Invalid SelectionPath specified."); return(null); } if (root == null) { Debug.Fail("No CategoryList specified."); return(null); } string[] pathValues = path.Path.Split(','); string categoryName = PersistedStateUtilities.Unescape(pathValues[0]); bool isAdvanced = pathValues.Length == 2; CategoryEntry category = root.FindCategory(categoryName); if (category == null) { return(null); } DependencyObject categoryVisual = root.FindCategoryEntryVisual(category); if (categoryVisual == null) { return(null); } DependencyObject searchStart; // For basic section, start at the root. // For advanced section, start at the advanced expander. // The next SelectionStop in both cases will be the section header SelectionStop. if (!isAdvanced) { searchStart = categoryVisual; } else { searchStart = VisualTreeUtils.GetNamedChild <FrameworkElement>(categoryVisual, "PART_AdvancedExpander"); } return(PropertySelection.FindNeighborSelectionStop <DependencyObject>(searchStart, SearchDirection.Next)); }
// ISelectionPathInterpreter Members public DependencyObject ResolveSelectionPath(CategoryList root, SelectionPath path, out bool pendingGeneration) { pendingGeneration = false; if (path == null || !string.Equals(PathTypeId, path.PathTypeId)) { Debug.Fail("Invalid SelectionPath specified."); return(null); } if (root == null) { Debug.Fail("No CategoryList specified."); return(null); } string[] pathValues = path.Path.Split(','); if (pathValues.Length < 1) { Debug.Fail("Invalid SelectionPath specified."); return(null); } // // Note: By the time this method gets called, all the visuals should have been expanded // and rendered. Hence, if we can't find a visual in the visual tree, it doesn't exist // and we shouldn't worry about trying to expand some parent visual and waiting for it // to render. // ModelCategoryEntry parentCategory; PropertyEntry currentProperty = root.FindPropertyEntry(PersistedStateUtilities.Unescape(pathValues[0]), out parentCategory); PropertyContainer currentContainer = root.FindPropertyEntryVisual(currentProperty, parentCategory, out pendingGeneration); DependencyObject lastFoundContainer = currentContainer; int pathIndex = 1; while (currentContainer != null && pathIndex < pathValues.Length) { SubPropertyEditor subPropertyEditor = VisualTreeUtils.GetTemplateChild <SubPropertyEditor>(currentContainer); if (subPropertyEditor == null) { break; } // If the subpropertyEditor is not expanded and is expandable, we won't be able to get the target property's visual // element, Expand it, set pendingGeneration to True, and return null. Expect the caller to call again. if (subPropertyEditor.IsExpandable && !subPropertyEditor.IsExpanded) { subPropertyEditor.IsExpanded = true; pendingGeneration = true; return(null); } PropertyEntry property = subPropertyEditor.FindSubPropertyEntry(PersistedStateUtilities.Unescape(pathValues[pathIndex])); if (property == null) { break; } currentContainer = subPropertyEditor.FindSubPropertyEntryVisual(property); lastFoundContainer = currentContainer ?? lastFoundContainer; pathIndex++; } if (lastFoundContainer == null) { return(null); } return(lastFoundContainer); }