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 属性)在用户设计器上设置,它应该可以在创建控件后使用。如您所见,我尝试将其放入构造函数但它不起作用,因为在将 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 回答