2014年1月13日月曜日

FormでShowing/Hidingイベントを実装

System.Windows.Forms.Formにありそうでないイベントの一つに、表示前/非表示前イベントがあります。
なければ作っちゃえということで、SetVisibleCoreをオーバーライドして実装してみました。
処理の流れは以下のようになります。

  1. 引数と現在のVisibleを比較し、等しければイベントを発生させずにSetVisibleCoreを呼んで終了する。
  2. 引数がtrueのとき、Showingイベントを発生させる
  3. 引数がfalseのとき、Hidingイベントを発生させる
  4. 2,3の結果、CancelEventArgs.Cancelがtrueのとき、引数を逆にしてSetVisibleCoreを呼び、終了する。
  5. SetVisibleCoreを呼び、終了する。

なお、注意点として、SetVisibleCoreでShow/Hideメソッドを呼ばないこと、Visibleプロパティを更新しないことがあります。これらに違反すると、StackOverflowExceptionが発生してしまいます。

サンプル

using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace Sample {
public class ShowingHidingForm : Form {
private event FormShowingEventHandler formShowing;
private event FormHidingEventHandler formHiding;
public event FormShowingEventHandler FormShowing {
add { formShowing += value; }
remove { formShowing -= value; }
}
public event FormHidingEventHandler FormHiding {
add { formHiding += value; }
remove { formHiding -= value; }
}
public ShowingHidingForm() {
formShowing += (sender, e) => {};
formHiding += (sender, e) => {};
}
protected override void SetVisibleCore (bool value) {
var current = Visible;
var toBe = value;
if (current == toBe) {
base.SetVisibleCore(toBe);
return;
}
if (toBe && !current) {
var e = new FormShowingEventArgs();
formShowing(this, e);
if (e.Cancel) {
toBe = current;
}
}
if (!toBe && current) {
var e = new FormHidingEventArgs();
formHiding(this, e);
if (e.Cancel) {
toBe = current;
}
}
base.SetVisibleCore(toBe);
}
public static void Main(string[] args) {
var form = new ShowingHidingForm();
form.FormShowing += (sender, e) => {
Console.WriteLine("Showing");
};
form.FormHiding += (sender, e) => {
Console.WriteLine("Hiding");
};
form.FormClosing += (sender, e) => {
form.Hide();
Console.WriteLine("Closing");
};
Application.Run(form);
}
}
public delegate void FormShowingEventHandler(object sender, FormShowingEventArgs e);
public delegate void FormHidingEventHandler(object sender, FormHidingEventArgs e);
public class FormShowingEventArgs : CancelEventArgs { }
public class FormHidingEventArgs : CancelEventArgs { }
}

参考

Form.SetVisibleCore メソッド

0 件のコメント:

コメントを投稿