LoginSignup
3

More than 5 years have passed since last update.

入れ子になった配下のコントロールをすべて列挙する(機能強化版)

Last updated at Posted at 2018-06-18

入れ子になった配下のコントロールをすべて列挙するをさらに改良して使いやすくしました。

列挙するコントロールの型を指定
列挙後のキャストが不要になる上に、不要なコントロールを列挙しないことによる高速化が期待できます。
抽出条件を指定できるようにする
列挙後にさらに条件を追加して対象コントロールを絞り込むことも多いだろうから、列挙メソッド側の機能として持った方がいいかなと。
IEnumerable<T> GetAllControls<T>(Control ctrl, Func<T, bool> predicate = null)
  where T : Control
{
  if (predicate == null) predicate = _ => true;
  IEnumerable<T> list = ctrl.Controls.OfType<T>().Where(predicate);
  return list.Concat(ctrl.Controls.Cast<Control>().SelectMany(child => GetAllControls<T>(child, predicate)));
}
使い方
//名前が"ID"で終わるテキストボックスをdisableに
foreach(var txtbox in GetAllControls<TextBox>(form, c => c.Name.EndsWith("ID")))
{
  txtbox.Enabled = false;
}

//名前が"panel"で始まるコンテナ直下のテキストボックスを非表示に
foreach(var txtbox in GetAllControls<TextBox>(form, c => c.Parent?.Name.StartWith("panel") ?? false))
{
  txtbox.Visible = false;
}

WPF版(論理ツリー)

IEnumerable<T> GetAllControls_WPF<T>(FrameworkElement element, Func<T, bool> predicate = null)
  where T : FrameworkElement
{
  if (predicate == null) predicate = _ => true;
  var childrenList = LogicalTreeHelper.GetChildren(element).OfType(FrameworkElement);
  IEnumerable<T> list = childrenList.OfType(T).Where(predicate);
  return list.Concat(childrenList.SelectMany(child => GetAllControls_WPF<T>(child, predicate)));
}

最近WPFいじってないのでビジュアルツリーでの列挙とか使い方はなし

修正(6/19)

predicateを省略した場合の対応が抜けていたので修正しました。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3