Сильверлайт:Найти все элементы управления типа в макете
-
21-09-2019 - |
Вопрос
Я ищу надежный метод создания списка элементов управления <Type>, содержащихся в определенном производном элементе управления <Panel>, - сюда входят те, которые являются прямыми дочерними элементами, а также те, которые являются дочерними элементами дочерних элементов и так далее.
Самый очевидный способ — просто сделать это рекурсивно:
Добавьте в список всех дочерних элементов этого элемента управления <Type>, затем повторите функцию для любого дочернего элемента этого элемента управления, который является <Panel> или потомком.
Однако меня беспокоит, что при этом не будут найдены все элементы управления в дереве: любой ContentControl может также содержать элемент управления <Type>, как и HeaderedContentControl или любой другой аналогичный элемент управления с одним или несколькими дочерними атрибутами/содержимым.
Есть ли какой-либо способ выполнить поиск по фактическому дереву макета, чтобы любой можно найти экземпляр определенного типа элемента управления, содержащегося без определенного родительского элемента?
Решение
Вот довольно наивный метод расширения:
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>();
Другие советы
Допустим, вы хотите найти поля со списком внутри пользовательского элемента управления, который начинается с GRID и имеет вложенные сетки, панели стека, холст и т. д.содержащий выпадающие списки
Imports System.Windows.Controls.Primitives
(или использование для C#)Dim ListOfComboBoxes = MAINGRID.GetVisualDescendants.OfType(Of ComboBox)
Вот и все...