Rationale
WinForms Developers need a more reliable way to check, if a custom control is currently in DesignMode. The Problem is that the DesignMode property of Control does only return true, if that control is a) actually sited, and b) then returns the DesignMode property of the Site.
In many cases, DesignMode that does not help: Whenever a control is part of a constituent control (like the TextBox control in NumericUpDown) or a UserControl, the individual controls making up the UserControl (constituent control) never get sited, and although there is a Site technically which could return true for DesignMode, from the perspective of that control, that never happens.
IMPORTANT NOTE: This API's purpose is not to provide a way to check, if a control is currently hosted by a Designer for License purposes, so for them to decide, if for example the Designer UI can be made accessible, if a necessary license is present. We would need a different infrastructure for that.
Proposed API:
Add a read-only property to Control, which returns a boolean:
public bool IsAncestorSiteInDesignMode
IsAncestorSiteInDesignMode would find the first sited root (parent/ancestor) control, test for that being sited and return DesignMode, thus a rather reliable way for a control to decide if according to its context it is considering itself to be in design mode (per the WinForms definition for DesignMode).
Will this feature affect UI controls?
No.
Practically, it could be looking something like this:
protected bool IsAncestorSiteInDesignMode =>
GetSitedParentSite(this) is ISite parentSite ? parentSite.DesignMode : false;
private ISite GetSitedParentSite(Control control) =>
control is null
? throw new ArgumentNullException(nameof(control))
: control.Site != null || control.Parent is null
? control.Site
: GetSitedParentSite(control.Parent);
Real World Scenario
Let's assume we have a custom control, which uses resources, but those resources should only be used at runtime (like connections to a database, or a connection to a web service).
That means, when ever not only this custom control is in its DesignMode...

...but also one of it's parents is in their DesignMode...

...it should not touch those resources.
As soon, however, as it detects that none of its ancestors is sited (or their sites are not reporting they are in DesignMode) it can assume it's safe to use those runtime-only resources:

From the custom control's point of view, such an implementation would look like this:
class CustomControl : Control
{
private Brush _cashedBackColorBrush = new SolidBrush(Color.DarkGray);
private bool _allowRunTimeOnlyResources;
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
if (!IsAncestorSiteInDesignMode)
{
_allowRunTimeOnlyResources = true;
}
}
protected override void OnPaint(PaintEventArgs e)
{
string drawText;
base.OnPaint(e);
e.Graphics.FillRectangle(_cashedBackColorBrush, ClientRectangle);
var canOrNot = _allowRunTimeOnlyResources ? "can" : "should not";
drawText = $"{this.Name} {canOrNot} use runtime resources currently.";
CenterString(drawText);
void CenterString(string paintText)
{
var textSize = e.Graphics.MeasureString(paintText, Font);
e.Graphics.DrawString(paintText,
Font,
Brushes.Black,
ClientSize.Width / 2 - textSize.Width / 2,
ClientSize.Height / 2 - textSize.Height / 2);
}
}
}
Note, that the test for being sited or not cannot be done in the custom control's constructor. Because at that time, neither the control nor its ancestor can be sited (or rather, it will probably not have ancestors at the time, since it has not been added to any control collection). So, the earliest point in time, when a custom control should check if it has been sited is after its handle got created. And since its handle gets created once the control should display its contends, in most of the cases this is an early enough point in time to decide, whether to use certain (runtime-only) types of resources or not.
Rationale
WinForms Developers need a more reliable way to check, if a custom control is currently in
DesignMode. The Problem is that theDesignModeproperty of Control does only return true, if that control is a) actually sited, and b) then returns theDesignModeproperty of the Site.In many cases,
DesignModethat does not help: Whenever a control is part of a constituent control (like theTextBoxcontrol inNumericUpDown) or a UserControl, the individual controls making up the UserControl (constituent control) never get sited, and although there is a Site technically which could returntrueforDesignMode, from the perspective of that control, that never happens.IMPORTANT NOTE: This API's purpose is not to provide a way to check, if a control is currently hosted by a Designer for License purposes, so for them to decide, if for example the Designer UI can be made accessible, if a necessary license is present. We would need a different infrastructure for that.
Proposed API:
Add a read-only property to
Control, which returns a boolean:IsAncestorSiteInDesignModewould find the first sited root (parent/ancestor) control, test for that being sited and returnDesignMode, thus a rather reliable way for a control to decide if according to its context it is considering itself to be in design mode (per the WinForms definition forDesignMode).Will this feature affect UI controls?
No.
Practically, it could be looking something like this:
Real World Scenario
Let's assume we have a custom control, which uses resources, but those resources should only be used at runtime (like connections to a database, or a connection to a web service).
That means, when ever not only this custom control is in its
DesignMode......but also one of it's parents is in their
DesignMode......it should not touch those resources.
As soon, however, as it detects that none of its ancestors is sited (or their sites are not reporting they are in
DesignMode) it can assume it's safe to use those runtime-only resources:From the custom control's point of view, such an implementation would look like this:
Note, that the test for being sited or not cannot be done in the custom control's constructor. Because at that time, neither the control nor its ancestor can be sited (or rather, it will probably not have ancestors at the time, since it has not been added to any control collection). So, the earliest point in time, when a custom control should check if it has been sited is after its handle got created. And since its handle gets created once the control should display its contends, in most of the cases this is an early enough point in time to decide, whether to use certain (runtime-only) types of resources or not.