Windowsフォームですべてのコントロール(ツールストリップとそのアイテム、bindingnavigatorとそのアイテムなど)を繰り返すことができる一般的な再帰的な方法はありますか?(それらのいくつかはControlクラスから継承されていません)または少なくともツールストリップとそのアイテム、bindingnavigatorとそのアイテムを繰り返しますか?
2 に答える
これは私がこの場合通常行うことです:
まず最初に、コントロールをパラメーターとして受け入れるデリゲートを定義します。
public delegate void DoSomethingWithControl(Control c);
次に、このデリゲートを最初のパラメーターとして受け取るメソッドと、それを再帰的に実行するためのコントロールを2番目のパラメーターとして実装します。このメソッドは、最初にデリゲートを実行し、次にコントロールのControlsコレクションをループして、それ自体を再帰的に呼び出します。ControlsはControlで定義されており、次のような単純なコントロールの場合は空のコレクションを返すため、これは機能します。
public void RecursivelyDoOnControls(DoSomethingWithControl aDel, Control aCtrl)
{
aDel(aCtrl);
foreach (Control c in aCtrl.Controls)
{
RecursivelyDoOnControls(aDel, c);
}
}
これで、各コントロールに対して実行するコードをメソッドに配置し、デリゲートを介してフォームで呼び出すことができます。
private void DoStg(Control c)
{
// whatever you want
}
RecursivelyDoOnControls(new DoSomethingWithControl(DoStg), yourForm);
編集:
ToolStripItemsも扱っているので、ジェネリックオブジェクトを扱うデリゲートを定義してから、再帰メソッドのさまざまなオーバーロードを記述できます。つまり、次のようなものです。
public delegate void DoSomethingWithObject(Object o);
public void RecursivelyDo(DoSomethingWithObject aDel, Control aCtrl)
{
aDel(aCtrl);
foreach (Control c in aCtrl.Controls)
{
RecursivelyDoOnControls(aDel, c);
}
}
public void RecursivelyDo(DoSomethingWithObject aDel, ToolStrip anItem)
{
aDel(anItem);
foreach (ToolstripItem c in anItem.Items)
{
RecursivelyDo(aDel, c);
}
}
public void RecursivelyDo(DoSomethingWithObject aDel, ToolStripDropDownButton anItem)
{
aDel(anItem);
foreach (ToolStripItem c in anItem.DropDownItems)
{
RecursivelyDo(aDel, c);
}
}
//and so on
の代わりにをToolStrip
使用し、から継承しないため、ここで問題が発生します。とから継承するので、せいぜいを取得できます。Items
Controls
ToolStripItem
Control
ToolStripItem
Control
Component
IEnumerable<Component>
これは、次の拡張メソッドを使用して実行できます。
public static class ComponentExtensions
{
public static IEnumerable<Component> GetAllComponents(this Component component)
{
IEnumerable<Component> components;
if (component is ToolStrip) components = ((ToolStrip)component).Items.Cast<Component>();
else if (component is Control) components = ((Control)component).Controls.Cast<Component>();
else components = Enumerable.Empty<Component>(); // figure out what you want to do here
return components.Concat(components.SelectMany(x => x.GetAllComponents()));
}
}
foreach
Windowsフォームでは、これらすべてのコンポーネントをループで処理できます。
foreach (Component component in this.GetAllComponents())
{
// Do something with component...
}
残念ながら、多くの手動による型チェックとキャストを行います。