私はC#WinFormを使用しています。十数個のテキストボックス、コンボボックス、チェックボックスがあります。winformは、データベースから取得された情報を表示します。無効になっているフォームに保存ボタンがあります。テキストボックス/コンボボックス/チェックボックスのいずれかが変更されたときに有効にできるようにしたいと思います。
これらの各アイテムに個別のイベントハンドラーを追加せずにこれを行う簡単な方法はありますか?
ここであなたをじっと見つめるのに十分です。必要に応じて、他のタイプforeach
のループを追加する必要がある場合があります。このアプローチでは、インスタンスごとではなく、タイプcontrol
ごとに数行のコードしか必要ないのは良いことです。Control
private void addHandlers()
{
foreach (TextBox control in Controls.OfType<TextBox>())
{
control.TextChanged += new EventHandler(OnContentChanged);
}
foreach (ComboBox control in Controls.OfType<ComboBox>())
{
control.SelectedIndexChanged += new EventHandler(OnContentChanged);
}
foreach (CheckBox control in Controls.OfType<CheckBox>())
{
control.CheckedChanged += new EventHandler(OnContentChanged);
}
}
protected void OnContentChanged(object sender, EventArgs e)
{
if (ContentChanged != null)
ContentChanged(this, new EventArgs());
}
public event EventHandler ContentChanged;
すべてのコントロールをサポートするようにメソッドを変更addHandlers
し、フォームにすべてのコントロールを追加した後でメソッドを呼び出すと、ContentChanged
フォーム上の何かが変更されたときに必要になる可能性のあることを実行するためにイベントをサブスクライブできます(つまり、保存ボタン)。
コントロールを確認し、すべてのコントロールに変更イベントをアタッチする必要があります。この記事では、同様の状況について説明します。
private void AssignHandlersForControlCollection(
Control.ControlCollection coll)
{
foreach (Control c in coll)
{
if (c is TextBox)
(c as TextBox).TextChanged
+= new EventHandler(SimpleDirtyTracker_TextChanged);
if (c is CheckBox)
(c as CheckBox).CheckedChanged
+= new EventHandler(SimpleDirtyTracker_CheckedChanged);
// ... apply for other desired input types similarly ...
// recurively apply to inner collections
if (c.HasChildren)
AssignHandlersForControlCollection(c.Controls);
}
}
それらすべてのイベントを処理する汎用イベントハンドラーを作成できますが、残念ながら、Visual Studioでイベントハンドラーを自動生成する方法はありません(存在する必要もありません)。
すべてのイベントを1つのハンドラーに接続し、それらすべてに同じ関数を呼び出させることができます。そこでは、ブールフラグmbSomethingChanged = trueがあり、保存ボタンが有効になります。保存するようにユーザーに警告する場合は、フォームを閉じるときにフラグを確認します。