.NET Windows Forms design time rules

后端 未结 5 1085
我在风中等你
我在风中等你 2020-12-30 08:53

I have an object that starts a thread, opens a file, and waits for input from other classes. As it receives input, it writes it to disk. Basically, it\'s a thread safe data

相关标签:
5条回答
  • 2020-12-30 09:15

    You can check the UsageMode of the LicenseManager, to check if the code is in design time or not.

    System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime

    Here is a quick example:

    using System;
    using System.ComponentModel;
    using System.Windows.Forms;
    
    namespace Test
    {
        public class ComponentClass : Component
        {
            public ComponentClass()
            {
                MessageBox.Show("Runtime!");
            }
        }
    }
    

    When this component gets add to your form in the designer, you will immediatly get a message box.

    To prevent this you can add a simple if statement to check if the code is not in design time

    using System;
    using System.ComponentModel;
    using System.Windows.Forms;
    
    namespace Test
    {
        public class ComponentClass : Component
        {
            public ComponentClass()
            {
                if (LicenseManager.UsageMode != LicenseUsageMode.Designtime)
                {
                    MessageBox.Show("Runtime!");
                }
            }
        }
    }
    

    After adding the if statement, the messagebox no longer appears when the component is added to the form via the designer.

    I hope this helps.

    -jeremy

    0 讨论(0)
  • 2020-12-30 09:17

    You could also use this to check if the Visual Studio Designer is running the code:

    public static bool DesignMode
    {
        get {  return (System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv"); }
    }
    

    Then in Form_Load:

    if (!DesignMode)
    {
        // Run code that breaks in Visual Studio Designer (like trying to get a DB connection)
    }
    

    However, this is less elegant than using the LicensManager.UsageMode, but it works (until Microsoft changes the name of the process Visual Studio runs under).

    0 讨论(0)
  • 2020-12-30 09:26

    Well, since this has been resurrected anyway, here's the function I use to determine whether I'm in design mode:

    public static bool IsAnyInDesignMode(Control control){
        while(control != null){
            if(control.Site != null && control.Site.DesignMode)
                return true;
            control = control.Parent;
        }
        return false;
    }
    

    This handles the case where the control is a child created by another control. The DesignMode property is only set for controls created by the designer itself.

    0 讨论(0)
  • 2020-12-30 09:33

    There are some things you shouldn't do with the designer. I don't have any hard evidence, but I found that the Windows Forms designer hates it when you take away the default constructor from it. Just go ahead and create new overloads, but leave the empty constructor in place.

    Also try to avoid doing Form_Load events in base classes you inherit from.

    0 讨论(0)
  • 2020-12-30 09:35

    The constructor of a control or form does not get executed when editing that class in the designer (nor does OnLoad get called). I've occasionally used this to set one value in the designer (eg. making its child controls all Visible in the designer) but override some of them to a different default value in the constructor (eg. hiding certain child controls which will only show in certain circumstances, such as an indicator on a status bar).

    However, the constructor does get executed if the control is placed as a child on another control or form in the designer. OnLoad gets executed as well. This may be how your logging code was getting accidentally triggered in the designer.

    For detecting design vs runtime, an answer to another question has screenshots of some emperical tests showing the values returned by some common approaches. It appears that a child control of a child control (two levels down) of the form or control being edited in the designer sees its own DesignMode == false, so the normal property check will fail to protect code (eg. in the OnLoad method) for controls nested within a control added in the designer. If you were checking DesignMode as one would expect, it could be the nesting which caused it to get around that check. It also always sees DesignMode == false within the constructor.

    Also, note that the LicenseManager.UsageMode check only sees DesignTime within the constructor; when OnLoad is called it is within a RunTime LicenseContext. The most complete solution seems to be to check LicenseManager.UsageMode in the constructor of the control or form (or component) and save the setting to a member variable or property which you can check later to avoid running code that should never run in the designer even when nested. There's also another approach in another answer to that other question which accounts for nesting but only works outside the constructor.

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