Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
985 views
in Technique[技术] by (71.8m points)

c# - Custom control derived from Component - OnCreate event?

I've created simple custom control - derived from Component class:

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;
    }
}

This control will be used to implement trial functionality in my application. Application (before it starts) should check trial remaining days and display notify dialog containing trial remaining days and textbox to write unlock key.

But I want to minimalise amount of code needed to wirte while using this control. So, my idea is to place trial check code inside my control and - just after control is created, it should display remaining days.

Trial period (TrialDays property) is set on user designer and it should be available to use just afeter control is created. As you can see, I tried to put this to constructor but it does not work, because constructor is called before setting TrialDays to valuje entered in user designer. And MessageBox always displays default value 0.

There is no any OnLoad or OnCreate events abailable to override. So, how can I automatically check trial status using value entered in designer?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The Component class is very simple, it just provides a way to host the component on a form at design time, giving access to its properties with the Properties window. But it has no notable useful events, using a component requires explicit code in the form. Like OpenFormDialog, nothing happens with it until you call its ShowDialog() method.

The constructor is usable but unfortunately it runs too early. The DesignMode property tells you whether or not a component runs at design time but it isn't set yet at constructor time. You'll need to delay the code and that's difficult because there are no other methods or events that run later.

A solution is to use the events of the form that you dropped the component on. Like the Load event. That requires some giddy code to coax the designer to tell you about the form. That technique is used by the ErrorProvider component, it requires exposing a property of type ContainerControl and overriding the Site property setter. Like this:

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");
        }
    }
}

The code is inscrutable, but you can be pretty sure it is reliable and stable because this is what the ErrorProvider component uses. Be sure to call Environment.Exit() when the trial period has ended, an exception isn't going to work well.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...