2

Componentクラスから派生した単純なカスタムコントロールを作成しました。

public partial class TrialChecker : Component
{
    private int _trialDays;


    public int TrialDays
    {
        get { return _trialDays; }
        set { _trialDays = value;}
    }

    public TrialChecker()
    {
        InitializeComponent();

        MessageBox.Show(TrialDays.ToString());

    }

    public int GetTrialDays()
    {
        return _trialDays;
    }
}

このコントロールは、アプリケーションに試用機能を実装するために使用されます。アプリケーション(開始前)は、試用期間の残り日数を確認し、試用期間の残り日数を含む通知ダイアログと、ロック解除キーを書き込むためのテキストボックスを表示する必要があります。

ただし、このコントロールを使用する際に必要なコードの量を最小限に抑えたいと思います。したがって、私の考えは、コントロール内にトライアルチェックコードを配置することです。コントロールが作成された直後に、残りの日数が表示されます。

試用期間(TrialDaysプロパティ)はユーザーデザイナーで設定され、コントロールが作成された直後に使用できるようになります。ご覧のとおり、これをコンストラクターに入れようとしましたが、ユーザーデザイナーに入力されたvalujeにTrialDaysを設定する前にコンストラクターが呼び出されるため、機能しません。また、MessageBoxは常にデフォルト値0を表示します。

オーバーライドできるOnLoadまたはOnCreateイベントはありません。では、デザイナーに入力した値を使用して、トライアルステータスを自動的に確認するにはどうすればよいですか?

4

1 に答える 1

4

Componentクラスは非常に単純で、デザイン時にフォーム上でコンポーネントをホストする方法を提供し、[プロパティ]ウィンドウでそのプロパティにアクセスできるようにします。ただし、注目すべき有用なイベントはありません。コンポーネントを使用するには、フォームに明示的なコードが必要です。OpenFormDialogと同様に、ShowDialog()メソッドを呼び出すまで何も起こりません。

コンストラクターは使用可能ですが、残念ながら実行が早すぎます。DesignModeプロパティは、コンポーネントが設計時に実行されるかどうかを示しますが、コンストラクター時にまだ設定されていません。コードを遅らせる必要がありますが、後で実行される他のメソッドやイベントがないため、これは困難です。

解決策は、コンポーネントをドロップしたフォームのイベントを使用することです。Loadイベントのように。それには、デザイナーにフォームについて教えてもらうためのちょっとしたコードが必要です。この手法はErrorProviderコンポーネントで使用され、ContainerControlタイプのプロパティを公開し、Siteプロパティセッターをオーバーライドする必要があります。このような:

using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Windows.Forms;

public partial class Component1 : Component {
    private ContainerControl parent;

    [Browsable(false)]
    public ContainerControl ContainerControl {
        get { return parent; }
        set {
            if (parent == null) {
                var form = value.FindForm();
                if (form != null) form.Load += new EventHandler(form_Load);
            }
            parent = value;
        }
    }

    public override ISite Site {
        set {
            // Runs at design time, ensures designer initializes ContainerControl
            base.Site = value;
            if (value == null) return;
            IDesignerHost service = value.GetService(typeof(IDesignerHost)) as IDesignerHost;
            if (service == null) return;
            IComponent rootComponent = service.RootComponent;
            this.ContainerControl = rootComponent as ContainerControl;
        }
    }

    void form_Load(object sender, EventArgs e) {
        if (!this.DesignMode) {
            MessageBox.Show("Trial");
        }
    }
}

コードは不可解ですが、これがErrorProviderコンポーネントが使用するものであるため、信頼性が高く安定していることを確信できます。試用期間が終了したら、必ずEnvironment.Exit()を呼び出してください。例外は、うまく機能しません。

于 2012-08-22T11:34:21.097 に答える