I have a very very annoying problem!
In my user control library I have a control with a panel inside, which can take content. If I build this dll and reference it to an project I normally can use this control and also add content to it. Now the problem: Everytime I build a new version of this control library and update/override the dll in the project I use this dll the control with the content will be rebuild and now the content is removed. How to fix this?
Best regards
Sven König
EDIT 1
Note: the panel I mean is a user control which have a Windows.Forms.Panel to store the content.
The designer of this user control is a "ParentControlDesigner".
EDIT 2
Sorry, the control to save to content is directly saved to the user control which is designed through ParentControlDesigner.
I've done this because if i use a Windows.Forms.Panel I have resizing options at design time. And this i don't want.
EDIT 3
Here is the Code for the GroupBox, where the content control is inside...
[Designer(typeof(BorderedGroupBoxDesigner))]
public partial class BorderedGroupBox : UserControl
{
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
internal Panel GroupingPanel { get; }
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
internal readonly Label TitelLabel;
private VisualStyleRenderer _renderer;
/// <summary>
/// Initializes the Control.
/// </summary>
public BorderedGroupBox()
{
InitializeComponent();
//Create TitleLabel
TitelLabel = new Label
{
Location = new Point(1, 1),
AutoSize = false,
TextAlign = ContentAlignment.MiddleLeft
};
//Create GroupingPanel
GroupingPanel = new Panel
{
Location = new Point(1, TitleHeight - 1)
};
//Create Container and add Panel
Control container = new ContainerControl
{
Dock = DockStyle.Fill,
Padding = new Padding(-1),
Controls = {TitelLabel, GroupingPanel}
};
//Add container and it's content to this control
Controls.Add(container);
//Set sizes of inner controls
TitelLabel.Size = new Size(Size.Width - 2, 20);
GroupingPanel.Size = new Size(Size.Width - 2, Size.Height - TitleHeight - 3);
//Set anchor of inner controls
TitelLabel.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
GroupingPanel.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
//Value defaults
BackgroundColor = SystemColors.Window;
BorderColor = SystemColors.GradientActiveCaption;
TitleBackColor = Color.FromKnownColor(KnownColor.DodgerBlue);
TitleFont = new Font("Calibri", TitleHeight - 9, FontStyle.Bold);
TitleFontColor = SystemColors.Window;
}
//Make default prope rty "BackColor" unvisible
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public sealed override Color BackColor { get; set; }
//Use "BackgroundColor" instead of default "BackColor"
/// <returns>The BackgroundColor associated with this control.</returns>
[Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
[Description("The backgroundcolor of the component.")]
[Category("Appearance")]
[DefaultValue(typeof(Color), "Window")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public Color BackgroundColor { get { return GroupingPanel.BackColor; } set { GroupingPanel.BackColor = value; } }
/// <returns>The BorderColor associated with this control.</returns>
[Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
[Description("Sets the border color.")]
[Category("Appearance")]
[DefaultValue(typeof(Color), "GradientActiveCaption")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public Color BorderColor { get { return BackColor; } set { BackColor = value; } }
/// <returns>The BorderColor of the title associated with this control.</returns>
[Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
[Description("Sets the title color.")]
[Category("Appearance")]
[DefaultValue(typeof(Color), "DodgerBlue")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public Color TitleBackColor { get { return TitelLabel.BackColor; } set { TitelLabel.BackColor = value; } }
/// <returns>The height of the title associated with this control.</returns>
[Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
[Description("Sets the title height in px.")]
[Category("Appearance")]
[DefaultValue(typeof(int), "20")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public int TitleHeight
{
get { return TitelLabel.Size.Height; }
set
{
TitelLabel.Size = new Size(TitelLabel.Size.Width, value);
GroupingPanel.Location = new Point(GroupingPanel.Location.X, value + 2);
GroupingPanel.Size = new Size(GroupingPanel.Size.Width, Size.Height - value - 3);
}
}
/// <returns>The font of the title associated with this control.</returns>
[Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
[Description("Sets the title font.")]
[Category("Appearance")]
[DefaultValue(typeof(Font), "Calibri; 11pt; style=Bold")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public Font TitleFont { get { return TitelLabel.Font; } set { TitelLabel.Font = value; } }
/// <returns>The ForeColor (color of the text) of the title associated with this control.</returns>
[Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
[Description("Sets the title font color.")]
[Category("Appearance")]
[DefaultValue(typeof(Color), "Window")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public Color TitleFontColor { get { return TitelLabel.ForeColor; } set { TitelLabel.ForeColor = value; } }
[Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
[Description("Sets the title text.")]
[Category("Appearance")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public override string Text { get { return TitelLabel.Text; } set { TitelLabel.Text = value; } }
/// <returns>Sets visibility of the design grid to easily align controls on grid.</returns>
[Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
[Description("Sets visibility of the design grid to easily align controls on grid.")]
[Category("Design")]
[DesignOnly(true)]
[DefaultValue(typeof(bool), "false")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public bool ShowDesignGrid
{
get { return GroupingPanel.Designer.DrawGridState; }
set
{
if (value)
GroupingPanel.Designer.EnableDrawGrid();
else
GroupingPanel.Designer.DisableDrawGrid();
Refresh();
}
}
/// <returns>Sets visibility of the design grid to easily align controls on grid.</returns>
[Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
[Description("Sets size of the design grid.")]
[Category("Design")]
[DesignOnly(true)]
[DefaultValue(typeof(Size), "8; 8")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public string DesignGridSize
{
get { return $"{GroupingPanel.Designer.GridSize.Width}; {GroupingPanel.Designer.GridSize.Height}"; }
set
{
var values = value.Split(';');
GroupingPanel.Designer.GridSize = new Size(int.Parse(values[0]), int.Parse(values[1]));
}
}
[Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public new Padding Padding
{
get { return GroupingPanel.Padding; }
set { GroupingPanel.Padding = value; }
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (!Focused || !Application.RenderWithVisualStyles) return;
if (_renderer == null)
{
var elem = VisualStyleElement.Button.PushButton.Normal;
_renderer = new VisualStyleRenderer(elem.ClassName, elem.Part, (int)PushButtonState.Normal);
}
var rc = _renderer.GetBackgroundContentRectangle(e.Graphics, new Rectangle(0, 0, Width, Height));
rc.Height--;
rc.Width--;
using (var p = new Pen(Brushes.Purple))
{
e.Graphics.DrawRectangle(p, rc);
}
}
}
internal class BorderedGroupBoxDesigner : ControlDesigner
{
internal static SelectionRulesEnum SelectionRule;
public override void Initialize(IComponent component)
{
base.Initialize(component);
EnableDragDrop(true);
var uc = component as BorderedGroupBox;
if (uc != null)
EnableDesignMode(uc.GroupingPanel, "Panel");
}
public override SelectionRules SelectionRules
{
get
{
switch (SelectionRule)
{
case SelectionRulesEnum.All:
return SelectionRules.Visible | SelectionRules.Moveable | SelectionRules.AllSizeable;
case SelectionRulesEnum.UpDown:
return SelectionRules.Visible | SelectionRules.Moveable | SelectionRules.TopSizeable | SelectionRules.BottomSizeable;
case SelectionRulesEnum.RightLeft:
return SelectionRules.Visible | SelectionRules.Moveable | SelectionRules.LeftSizeable | SelectionRules.RightSizeable;
case SelectionRulesEnum.None:
return SelectionRules.Visible | SelectionRules.Moveable;
default:
return SelectionRules.Visible | SelectionRules.Moveable;
}
}
}
internal enum SelectionRulesEnum
{
All,
UpDown,
RightLeft,
None
}
}
And here is the "Panel"...
[Designer(typeof(NonSizeablePanel_ParentDesigner))]
internal partial class Panel : UserControl
{
internal NonSizeablePanel_ParentDesigner Designer;
internal Panel()
{
InitializeComponent();
}
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public new Point Location { get { return base.Location; } set { base.Location = value; } }
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public new AnchorStyles Anchor { get { return base.Anchor; } set { base.Anchor = value; } }
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public new Size Size { get { return base.Size; } set { base.Size = value; } }
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public new bool AutoScroll { get { return base.AutoScroll; } set { base.AutoScroll = value; } }
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public new Size AutoScrollMargin { get { return base.AutoScrollMargin; } set { base.AutoScrollMargin = value; } }
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public new Size AutoScrollMinSize { get { return base.AutoScrollMinSize; } set { base.AutoScrollMinSize = value; } }
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public new bool AutoSize { get { return base.AutoSize; } set { base.AutoSize = value; } }
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public new DockStyle Dock { get { return base.Dock; } set { base.Dock = value; } }
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public new Padding Margin { get { return base.Margin; } set { base.Margin = value; } }
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public new Padding Padding { get { return base.Padding; } set { base.Padding = value; } }
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public new Size MaximumSize { get { return base.MaximumSize; } set { base.MaximumSize = value; } }
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public new Size MinimumSize { get { return base.MinimumSize; } set { base.MinimumSize = value; } }
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public new bool Visible { get { return base.Visible; } set { base.Visible = value; } }
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public new bool Enabled { get { return base.Enabled; } set { base.Enabled = value; } }
}
internal class NonSizeablePanel_ParentDesigner : ParentControlDesigner
{
public override void Initialize(IComponent component)
{
base.Initialize(component);
var userControl = component as Panel;
if (userControl != null)
userControl.Designer = this;
}
internal new Size GridSize
{
get { return base.GridSize; }
set { base.GridSize = value; }
}
internal bool DrawGridState => DrawGrid;
internal void EnableDrawGrid()
{
DrawGrid = true;
}
internal void DisableDrawGrid()
{
DrawGrid = false;
}
protected override bool DrawGrid { get; set; }
//Disable any sizing grips
public override SelectionRules SelectionRules => SelectionRules.None;
}
Here is the solution.
The problem was adding the controls to a child user control. So the solution is to add the controls directly to the user control it self and overriding the OnControlAdded event to bring the added control in front.
protected override void OnControlAdded(ControlEventArgs e)
{
base.OnControlAdded(e);
e.Control.BringToFront();
}
Because if I add controls in design time, the designer showed the added control
correctly as long as I don't build or rebuild.
At the moment I build/rebuild the form the designer tells the user control to add a control.
The user control added the control correctly but under the ContainerControl which contains the basic controls. => the control was no longer visible.
Here is the new code of the user control:
[Designer(typeof(BorderedGroupBoxDesigner))]
[DefaultEvent("Load")]
public sealed partial class BorderedGroupBox : UserControl
{
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
internal readonly Panel BackgroundPanel;
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
internal readonly Label TitelLabel;
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
internal new readonly ContainerControl Container;
private VisualStyleRenderer _renderer;
private int _contentPanelTop => TitleHeight + 2;
private int _contentPanelLeft => 1;
private int _contentPanelWidth => Size.Width - 2;
private int _contentPanelHeight => Size.Height - TitleHeight;
/// <summary>
/// Initializes the Control.
/// </summary>
public BorderedGroupBox()
{
InitializeComponent();
//Create TitleLabel
if (TitelLabel == null)
TitelLabel = new Label
{
Location = new Point(1, 1),
AutoSize = false,
TextAlign = ContentAlignment.MiddleLeft
};
//Create BackgroundPanel
if (BackgroundPanel == null)
BackgroundPanel = new Panel
{
Location = new Point(1, TitleHeight - 1)
};
//Create Container and add Panel
if (Container == null)
Container = new ContainerControl
{
Dock = DockStyle.Fill,
Padding = new Padding(-1),
Controls = { TitelLabel, BackgroundPanel }
};
//Add container and it's content to this control
Controls.Add(Container);
//Set sizes of inner controls
TitelLabel.Size = new Size(Size.Width - 2, 20);
BackgroundPanel.Size = new Size(Size.Width - 2, Size.Height - TitleHeight - 3);
//Set anchor of inner controls
TitelLabel.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
BackgroundPanel.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
//Value defaults
BackgroundColor = SystemColors.Window;
BorderColor = SystemColors.GradientActiveCaption;
TitleBackColor = Color.FromKnownColor(KnownColor.DodgerBlue);
TitleFont = new Font("Calibri", TitleHeight - 9, FontStyle.Bold);
TitleFontColor = SystemColors.Window;
AllowDrop = true;
}
//Make default property "BackColor" unvisible
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public override Color BackColor { get; set; }
//Use "BackgroundColor" instead of default "BackColor"
/// <returns>The BackgroundColor associated with this control.</returns>
[Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
[Description("The backgroundcolor of the component.")]
[Category("Appearance")]
[DefaultValue(typeof(Color), "Window")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public Color BackgroundColor { get { return BackgroundPanel.BackColor; } set { BackgroundPanel.BackColor = value; } }
/// <returns>The BorderColor associated with this control.</returns>
[Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
[Description("Sets the border color.")]
[Category("Appearance")]
[DefaultValue(typeof(Color), "GradientActiveCaption")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public Color BorderColor { get { return BackColor; } set { BackColor = value; } }
/// <returns>The BorderColor of the title associated with this control.</returns>
[Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
[Description("Sets the title color.")]
[Category("Appearance")]
[DefaultValue(typeof(Color), "DodgerBlue")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public Color TitleBackColor { get { return TitelLabel.BackColor; } set { TitelLabel.BackColor = value; } }
/// <returns>The height of the title associated with this control.</returns>
[Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
[Description("Sets the title height in px.")]
[Category("Appearance")]
[DefaultValue(typeof(int), "20")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public int TitleHeight
{
get { return TitelLabel.Size.Height; }
set
{
TitelLabel.Size = new Size(TitelLabel.Size.Width, value);
BackgroundPanel.Location = new Point(BackgroundPanel.Location.X, value + 2);
BackgroundPanel.Size = new Size(BackgroundPanel.Size.Width, Size.Height - value - 3);
}
}
/// <returns>The font of the title associated with this control.</returns>
[Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
[Description("Sets the title font.")]
[Category("Appearance")]
[DefaultValue(typeof(Font), "Calibri; 11pt; style=Bold")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public Font TitleFont { get { return TitelLabel.Font; } set { TitelLabel.Font = value; } }
/// <returns>The ForeColor (color of the text) of the title associated with this control.</returns>
[Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
[Description("Sets the title font color.")]
[Category("Appearance")]
[DefaultValue(typeof(Color), "Window")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public Color TitleFontColor { get { return TitelLabel.ForeColor; } set { TitelLabel.ForeColor = value; } }
[Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
[Description("Sets the title text.")]
[Category("Appearance")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public override string Text { get { return TitelLabel.Text; } set { TitelLabel.Text = value; } }
/// <summary>Raises the <see cref="E:System.Windows.Forms.Control.Paint" /> event.</summary>
/// <param name="e">A <see cref="T:System.Windows.Forms.PaintEventArgs" /> that contains the event data. </param>
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (!Focused || !Application.RenderWithVisualStyles) return;
if (_renderer == null)
{
var elem = VisualStyleElement.Button.PushButton.Normal;
_renderer = new VisualStyleRenderer(elem.ClassName, elem.Part, (int)PushButtonState.Normal);
}
var rc = _renderer.GetBackgroundContentRectangle(e.Graphics, new Rectangle(0, 0, Width, Height));
rc.Height--;
rc.Width--;
using (var p = new Pen(Brushes.Purple))
{
e.Graphics.DrawRectangle(p, rc);
}
}
/// <summary>Raises the <see cref="E:System.Windows.Forms.Control.ControlAdded" /> event.</summary>
/// <param name="e">A <see cref="T:System.Windows.Forms.ControlEventArgs" /> that contains the event data. </param>
protected override void OnControlAdded(ControlEventArgs e)
{
base.OnControlAdded(e);
e.Control.BringToFront();
}
}
internal class BorderedGroupBoxDesigner : ParentControlDesigner
{
internal static SelectionRulesEnum SelectionRule;
public override void Initialize(IComponent component)
{
base.Initialize(component);
EnableDragDrop(true);
}
public override SelectionRules SelectionRules
{
get
{
switch (SelectionRule)
{
case SelectionRulesEnum.All:
return SelectionRules.Visible | SelectionRules.Moveable | SelectionRules.AllSizeable;
case SelectionRulesEnum.UpDown:
return SelectionRules.Visible | SelectionRules.Moveable | SelectionRules.TopSizeable | SelectionRules.BottomSizeable;
case SelectionRulesEnum.RightLeft:
return SelectionRules.Visible | SelectionRules.Moveable | SelectionRules.LeftSizeable | SelectionRules.RightSizeable;
case SelectionRulesEnum.None:
return SelectionRules.Visible | SelectionRules.Moveable;
default:
return SelectionRules.Visible | SelectionRules.Moveable;
}
}
}
internal enum SelectionRulesEnum
{
All,
UpDown,
RightLeft,
None
}
}