C#
WPF

ビジュアルツリーの子孫要素を列挙する


やりたいこと

ビジュアルツリーから子孫要素をIEnumerableとして取得する。


実装

VisualTreeHelperクラスを使えば、子孫要素の取得自体はできるのだが使いにくい。そこで子孫要素を列挙する拡張メソッドをDependencyObjectに作成する。


拡張メソッド

using System;

using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Media;

namespace Sample {
public static class DependencyObjectExtensions {
public static IEnumerable<DependencyObject> Children(this DependencyObject obj) {
if (obj == null)
throw new ArgumentNullException(nameof(obj));

return Enumerable.Range(0, VisualTreeHelper.GetChildrenCount(obj))
.Select(i => VisualTreeHelper.GetChild(obj, i))
.Where(x => x != null);
}

public static IEnumerable<DependencyObject> Descendants(this DependencyObject obj) {
if (obj == null)
throw new ArgumentNullException(nameof(obj));

foreach (var child in obj.Children()) {
yield return child;
foreach (var grandChild in child.Descendants())
yield return grandChild;
}
}

public static IEnumerable<T> Descendants<T>(this DependencyObject obj) where T : DependencyObject {
if (obj == null)
throw new ArgumentNullException(nameof(obj));

return obj.Descendants().OfType<T>();
}
}
}



使い方

var headers = grid.Descendants<DataGridColumnHeader>();