Silverlight: найти все элементы управления типа в макете
Я ищу надежный метод для построения списка элементов управления , содержащихся в конкретном производном элементе управления - сюда входят те, которые являются прямыми дочерними элементами, и те, которые являются дочерними элементами детей и так далее.
Самым очевидным способом было просто сделать это рекурсивно:
Добавьте в список все дочерние элементы этого элемента управления , затем повторите функцию для любого дочернего элемента этого элемента управления, который является или потомком.
Однако я обеспокоен тем, что это не найдет всех элементы управления в дереве-любой ContentControl может также содержать элемент управления , как и HeaderedContentControl или любой другой подобный элемент управления с одним или несколькими дочерними атрибутами/content.
Есть ли какие-либо средства выполнения поиска по фактическому дереву компоновки, чтобы любой экземпляр определенного типа элемента управления, содержащегося без определенного родителя, можно было найти?
2 ответа:
Вот довольно наивный метод расширения: -
public static class VisualTreeEnumeration { public static IEnumerable<DependencyObject> Descendents(this DependencyObject root) { int count = VisualTreeHelper.GetChildrenCount(root); for (int i=0; i < count; i++) { var child = VisualTreeHelper.GetChild(root, i); yield return child; foreach (var descendent in Descendents(child)) yield return descendent; } } }
У этого подхода есть недостаток, что он предполагает, что никакие изменения не происходят в членстве дерева во время его выполнения. Это может быть смягчено при использовании с помощью ToList ().
Теперь вы можете выполнить свои требования с помощью LINQ: -
var qryAllButtons = myPanel.Descendents().OfType<Button>();
Предположим, вы хотите найти comboboxes внутри userControl, который начинается с сетки и имеет вложенные сетки, stackpanels, canvas и т. д. содержащий элементы для определения
Imports System.Windows.Controls.Primitives
(или использование для C#)Dim ListOfComboBoxes = MAINGRID.GetVisualDescendants.OfType(Of ComboBox)
Вот и все...