C# Windows フォーム コントロール ライブラリを使用して複合コントロールを作成しました。新しいコントロールをテスト プログラムで使用するときに、新しいコントロールの名前が設計時にいつ変更されたかを検出する方法を見つけたいのですが、どうすればよいですか?
3 に答える
この例のようにIComponentChangeService
(in )を使用できます。System.ComponentModel.Design
public class MyControl : UserControl
{
public event EventHandler NameChanged;
protected virtual void OnNameChanged()
{
EventHandler handler = NameChanged;
if (handler != null) handler(this, EventArgs.Empty);
}
protected override void OnCreateControl()
{
base.OnCreateControl();
IComponentChangeService changeService = (IComponentChangeService)GetService(typeof(IComponentChangeService));
if (changeService == null) return; // not provided at runtime, only design mode
changeService.ComponentChanged -= OnComponentChanged; // to avoid multiple subscriptions
changeService.ComponentChanged += OnComponentChanged;
}
private void OnComponentChanged(object sender, ComponentChangedEventArgs e)
{
if (e.Component == this && e.Member.Name == "Name")
OnNameChanged();
}
}
このサービスは、実行時ではなく、設計モードでのみ提供されます。
イベントの購読を解除し、再度購読しますComponentChanged
(複数の購読を避けるため)。
イベント ハンドラーOnComponentChanged
で、自分の名前が変更されたかどうかを確認し、NameChanged
イベントを発生させます。
イベント「OnNameChanged」はなく、Name-Property 自体は仮想ではないため、オーバーライドできません...残念ながら、確実な方法はありません...
いくつかの提案:
「new」で独自の Name-Property を定義しますが、継承されたクラスはこれを自動的に追い越さず、さらに悪いことに、Control へのキャストと Control.Name の使用は、プロパティを回避するだけです...
仮想の「MyName」プロパティを定義し、これをコントロールの名前プロパティに書き込むためだけに使用します。Control.Name の呼び出しはまだ通過しますが、少なくとも MyName の使用を強制できます...
コンストラクター内で名前をパッファーし、タイマーを定義して、何かが変更された場合に定期的に確認します
全体として、私はそれらのいずれも使用しないことを認めなければなりません...あなたが何を達成したいのか正確にはわかりませんが、この目標を達成するための別のアプローチを見つけようとします...
public MyControl : UserControl
{
public new string Name
{
get { return base.Name; }
set
{
base.Name = value;
// handle the name change here....
}
}
}