WPF Windowに配置されたコントロールを列挙する

  • 8
    Like
  • 0
    Comment
More than 1 year has passed since last update.

LogicalTreeHelperクラスのGetChildren()メソッドを使用することで、DependencyObjectの子要素を取得することができます。
これを再帰的に呼び出すことで、Windowに配置されたすべてのコントロールを列挙することが可能です。

参考:MSDN : LogicalTreeHelper.GetChildren メソッド (DependencyObject)

サンプルコード

DependencyObjectの拡張メソッドとして実装してみました。

DependencyObjectExtension.cs
public static class DependencyObjectExtension
{
    /// <summary>
    /// WalkInChildrenメソッドの本体
    /// </summary>
    /// <param name="obj">DependencyObject</param>
    /// <param name="act">Action</param>
    private static void Walk(DependencyObject obj, Action<DependencyObject> act)
    {
        foreach (var child in LogicalTreeHelper.GetChildren(obj))
        {
            if (child is DependencyObject)
            {
                act(child as DependencyObject);
                Walk(child as DependencyObject, act);
            }
        }
    }

    /// <summary>
    /// 子オブジェクトに対してデリゲートを実行する
    /// </summary>
    /// <param name="obj">this : DependencyObject</param>
    /// <param name="act">デリゲート : Action</param>
    public static void WalkInChildren(this DependencyObject obj, Action<DependencyObject> act)
    {
        if (act == null)
            throw new ArgumentNullException();

        Walk(obj, act);
    }
}
csharp:MainWindow.xaml.cs
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        // コントロールのロードが完了したら、すべてのコントロールをDebugウィンドウに出力する
        Loaded += (o, e) =>
        {
            this.WalkInChildren(child =>
            {
                System.Diagnostics.Debug.WriteLine(child);
            });
        };
    }
}

実行例

適当なWindowに対して実行してみた結果。

System.Windows.Controls.Grid
System.Windows.Controls.RowDefinition
System.Windows.Controls.RowDefinition
System.Windows.Controls.RowDefinition
System.Windows.Controls.Grid
System.Windows.Controls.ColumnDefinition
System.Windows.Controls.ColumnDefinition
System.Windows.Controls.ListBox Items.Count:4
System.Windows.Controls.StackPanel
System.Windows.Controls.Button: Add Item
System.Windows.Controls.Button: Delete Item
...