I have a winforms user control that comprises of a single TableLayoutPanel. The user control has an ObservableCollection<Label>
as a public property. Each Label should be shown in a row of the TableLayoutPanel. I want to be able to add or remove Labels either at design-time or programmatically.
I added an instance of the user control to the main form using the designer. The collection shows in the property-window of the designer, and upon clicking on it, a window opens where I can add/remove Labels and change the properties of each single Label. When I add Labels they do show up in the TableLayoutPanel.
However, when I run the project (having added Labels to the collection prior) the form is empty.
I observed that the designer adds each Label to Form1.Designer.cs as private field (eg., private Label label1;
). Though the form is empty (as is the collection) after running the project, the Labels themselves are not deleted.
This is my code:
namespace TestTableLayoutPanel
{
public partial class TLPsLabels : UserControl
{
public TLPsLabels()
{
InitializeComponent();
labels = new();
labels.CollectionChanged += OnLabelsChanged;
}
private ObservableCollection<Label> labels;
public ObservableCollection<Label> Labels { get { return labels; } }
private void OnLabelsChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
tLP1.RowStyles.Clear();
tLP1.RowCount = labels.Count;
tLP1.ColumnCount = 1;
for (int i = 0; i < tLP1.RowCount; i++)
{
tLP1.RowStyles.Add(new RowStyle(SizeType.Percent, 100.0F));
tLP1.Controls.Add(labels[i]);
labels[i].Anchor = AnchorStyles.None;
// Do some other stuff, like resizing tLP1's parent control, etc.
}
}
}
}
tLP1
is the TableLayoutPanel which should contain the Labels.
I know the problem is labels = new();
in the user control's constructor. It "overrides" the collection made at design-time. However, I have no idea how to solve this. Maybe even another approach is needed?
This code is just for testing/learning. Instead of labels, I want to show other, more complex user controls inside the TableLayoutPanel.