Like many others, I have had this problem several times already when designing Windows Forms UserControls.
But today, I had a situation where none of the mentioned solutions worked for me.
The problem is, that LicenseManager.UsageMode
only works reliably in the constructor, while DesignMode
only works outside the constructor and not always. This is my experience, and this is what is said in a discussion on GitHub.
And another problem comes with inheritance, and embedding user controls in another user controls in another user controls. At the latest in the 2nd level of embedding a user controls, both ways fail!
This can be shown in the UserControls that I created for this test. Every UC has 3 labels:
its (project name)
and type name
The values of
DesignMode
(true
: "DM=1"
),
LicenseManager.UsageMode == LicenseUsageMode.Designtime
, queried locally, (true
: "local_LM-DT=1")
LicenseManager.UsageMode == LicenseUsageMode.Designtime
, queried from a private field that was written in the constructor (true
: "ctor_LM-DT=1")
all taken inside the constructor ("CTOR") and inside a method that was called from the constructor ("CFCtor")
The same values as in 2)
all taken inside the Load
event ("Load()") and inside a method that was called from the Load
event ("CFLoad")
The UserControls and the Form that I created are (all screenshots shown them in the WinForms Designer):
UserControl1
:
The Designer does not execute the construtor or events, therefore the labels are not filled.
UserControl1a
:
- inherits from
UserControl1
- contains 2 more labels
The Designer executes the construtor and events of the parent UserControl.
UserControl2
: contains
- contains 3 labels
- contains 1
UserControl1
- contains 1
UserControl1a
The Designer executes the construtors and events of the embedded UserControls.
Only 1 level of embedding.
UserControl3
:
- contains 3 labels
- contains 1
UserControl2
The Designer executes the construtors and events of the embedded UserControls.
2 level of embedding: The values inside the UserControl at 2nd embedding level are wrong.
Form1
:
- contains 3 labels
- contains 1
UserControl1
- contains 1
UserControl1a
- contains 1
UserControl2
- contains 1
UserControl3
.
The Designer executes the construtors and events of the embedded UserControls.
3 level of embedding: The values inside the UserControl at 2nd and 3rd embedding level are wrong.
As you can see from the screenshots, "ctor_LM-DT" is always 1.
This means, that storing the value from the LicenseManager in a member field is necessary to get a valid status of the Designer usage:
private LicenseUsageMode m_ctorLMUsageMode = LicenseManager.UsageMode;
For the sake of completeness, here's some of my code that can be used to reproduce the test:
public static string CreateText(bool i_isInDesignMode, LicenseUsageMode i_localLicenseUsageMode, LicenseUsageMode i_ctorLicenseUsageMode)
{
return $"DM={(i_isInDesignMode ? 1 : 0)} local_LM-DT={(i_localLicenseUsageMode == LicenseUsageMode.Designtime ? 1 : 0)} ctor_LM-DT={(i_ctorLicenseUsageMode == LicenseUsageMode.Designtime ? 1 : 0)}";
}
The other UserControls are identical or similar:
public partial class UserControl1 : UserControl
{
private LicenseUsageMode m_ctorLMUsageMode = LicenseManager.UsageMode;
public UserControl1()
{
InitializeComponent();
label2.Text = $"CTOR: {CInitTester.CreateText (DesignMode, LicenseManager.UsageMode, m_ctorLMUsageMode)}";
CalledFromCtor();
}
private void UserControl1_Load(object sender, EventArgs e)
{
label3.Text = $"Load(): {CInitTester.CreateText(DesignMode, LicenseManager.UsageMode, m_ctorLMUsageMode)}";
CalledFromLoad();
}
private void CalledFromCtor()
{
label2.Text += $"\r\nCFCtor: {CInitTester.CreateText (DesignMode, LicenseManager.UsageMode, m_ctorLMUsageMode)}";
}
private void CalledFromLoad()
{
label3.Text += $"\r\nCFLoad: {CInitTester.CreateText (DesignMode, LicenseManager.UsageMode, m_ctorLMUsageMode)}";
}
}
ISite.DesignMode
. – Hayrick