Silverlight: найти все элементы управления типа в макете


Я ищу надежный метод для построения списка элементов управления , содержащихся в конкретном производном элементе управления - сюда входят те, которые являются прямыми дочерними элементами, и те, которые являются дочерними элементами детей и так далее.

Самым очевидным способом было просто сделать это рекурсивно:
Добавьте в список все дочерние элементы этого элемента управления , затем повторите функцию для любого дочернего элемента этого элемента управления, который является или потомком.

Однако я обеспокоен тем, что это не найдет всех элементы управления в дереве-любой ContentControl может также содержать элемент управления , как и HeaderedContentControl или любой другой подобный элемент управления с одним или несколькими дочерними атрибутами/content.

Есть ли какие-либо средства выполнения поиска по фактическому дереву компоновки, чтобы любой экземпляр определенного типа элемента управления, содержащегося без определенного родителя, можно было найти?

2 7

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 и т. д. содержащий элементы для определения

  1. Imports System.Windows.Controls.Primitives (или использование для C#)
  2. Dim ListOfComboBoxes = MAINGRID.GetVisualDescendants.OfType(Of ComboBox)

Вот и все...