Custom control derived from Component - OnCreate event?

前端 未结 1 462
南笙
南笙 2020-12-20 04:08

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

public partial class TrialChecker : Component
{
    private int _trialDays;


    public          


        
相关标签:
1条回答
  • 2020-12-20 04:44

    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.

    0 讨论(0)
提交回复
热议问题