I'm in agreement with Fildor's comment because implementing an interface can be quite a bit more flexible and extensible. There's no requirement to inherit any particular base class, and it's possible to mix-and-match interfaces as a form of de facto multiple inheritance. In this case, it might be especially useful to include an event so the UserControl can notify the parent when something happens that might require a status update.
interface IStatusProvider
{
string Status { get; }
event EventHandler StatusUpdated;
}
Example of a CustomUserControl : UserControl, IStatusProvider
class UserControlTypeA : UserControl, IStatusProvider
{
public UserControlTypeA()
{
_checkBox =
new CheckBox
{
Text = "CheckBox",
Size = new Size(150, 50),
TextAlign = ContentAlignment.MiddleCenter,
Appearance = Appearance.Button,
};
_checkBox.CheckedChanged += (sender, e) =>
StatusUpdated?.Invoke(this, EventArgs.Empty);
Controls.Add(_checkBox);
AutoSizeMode = AutoSizeMode.GrowAndShrink;
AutoSize = true;
}
private readonly CheckBox _checkBox;
public event EventHandler StatusUpdated;
public string Status => $"{GetType().Name}: {_checkBox.Checked}";
}
The various different UserControl types can be instantiated as a collection of IStatusProvider:
IStatusProvider[] UserControls = new IStatusProvider[]
{
new UserControlTypeA(),
new UserControlTypeB(),
new UserControlTypeC(),
};
You can use an implicit cast in a foreach, for example to use it as a Control:
// Implicit cast from IStatusProvider to Control
foreach (Control control in UserControls)
{
flowLayoutPanel.Controls.Add(control);
}
Otherwise, the variant in the foreach will evaluate to IStatusProvider and this is where the different user controls will provide different responses to Status:
// IStatusProvider
foreach (var statusProvider in UserControls)
{
statusProvider.StatusUpdated += onAnyStatusUpdated;
}
private void onAnyStatusUpdated(object sender, EventArgs e)
{
foreach (var statusProvider in UserControls)
{
textBoxMultiline.AppendText($"{statusProvider.Status}{Environment.NewLine}");
}
textBoxMultiline.AppendText(Environment.NewLine);
}
The result of iterating the UserControls collection is shown here, where the flowLayoutPanel is on the left and the status updates are shown on the right.
