2012-08-22 71 views
2

我創建簡單的自定義控制 - 從Component類派生:從Component - OnCreate事件派生的自定義控件?

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屬性)是在用戶設計器上設置的,它應該可用於僅使用afeter控件創建。正如你所看到的,我試圖把它放到構造函數中,但它不起作用,因爲在將TrialDays設置爲在用戶設計器中輸入值之前調用構造函數。並且MessageBox始終顯示默認值0.

沒有任何可以覆蓋的OnLoad或OnCreate事件。那麼,如何使用設計師輸入的值自動檢查試用狀態?

回答

4

Component類非常簡單,只是提供了一種在設計時託管表單上的組件的方法,通過Properties窗口可以訪問其屬性。但它沒有值得注意的有用事件,使用一個組件需要在表單中有明確的代碼。像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(),但異常不會很好。

+0

我發現爲組件定義LayOut事件,然後檢查DesignTime == false ...在此時我可以訪問該組件,因爲它在運行時出現...很有用。 – BillW