Follow-up from: Windows Forms designer, ObservableCollection<Control> and TableLayoutPanel, controls added at design-time don't show anymore when project is run
I'm writing a custom control which inherits from TableLayoutPanel and has a custom designer. The designer has a Collection of Labels which is exposed to Visual Studio Designer's properties window.
This is what I have so far:
using Microsoft.DotNet.DesignTools.Designers;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.ObjectModel;
using System.ComponentModel;
namespace TestTableLayoutPanel
{
[Designer(typeof(TlpLabelsDesigner))]
public partial class TlpLabels : TableLayoutPanel
{
public TlpLabels()
{
InitializeComponent();
}
}
public class TlpLabelsDesigner : ControlDesigner
{
public override void Initialize(IComponent component)
{
base.Initialize(component);
labels.CollectionChanged += OnLabelsChanged;
}
private readonly ObservableCollection<Label> labels = new ObservableCollection<Label>();
public ObservableCollection<Label> Labels { get { return labels; } }
private void OnLabelsChanged(object? sender, EventArgs e)
{
TableLayoutPanel tlp = (TableLayoutPanel)Control;
tlp.RowStyles.Clear();
tlp.RowCount = Labels.Count;
for(int i = 0; i < tlp.RowCount; i++)
tlp.RowStyles.Add(new RowStyle(SizeType.Percent, 100.0F / tlp.RowCount));
for (int j = 0; j < tlp.RowCount; j++)
{
labels[j].Anchor = AnchorStyles.None;
labels[j].TextAlign = ContentAlignment.MiddleCenter;
tlp.Controls.Add(labels[j]);
}
}
private readonly string[] RemovedProperties = new string[]
{
"Cell", "CellBorderStyle", "Column", "ColumnCount", "ColumnSpan", "GrowStyle", "Row", "RowCount", "RowSpan"
};
protected override void PreFilterProperties(IDictionary properties)
{
foreach (string prop in RemovedProperties)
properties.Remove(prop);
string desc = "Auflistung aller Labels, die im TableLayoutPanel eingeordnet und angezeigt werden.";
PropertyDescriptor pd = TypeDescriptor.CreateProperty(typeof(TlpLabelsDesigner), "Labels", typeof(ObservableCollection<Label>),
new Attribute[] { new DesignOnlyAttribute(false),
new BrowsableAttribute(true),
new CategoryAttribute("Layout"),
new DescriptionAttribute(desc)});
properties.Add("Labels", pd);
base.PreFilterProperties(properties);
}
}
}
The problems I have with it:
- When I open the collection editor and add Labels, the code to initialize them is put into Form1.Designer.cs, instead of TlpLabels.Designer.cs
- When I run and close the application and open the collection editor again, the list is empty. Just the list though; initialization code in Form1.Designer.cs is still there, and the labels are still shown in the form.