I am dynamically adding and replacing controls in a winform panel at runtime
Even though all works I have been told to implement interfaces rather than inheriting from a baseUserControl.
I am all for it but I dont see how I can I achieve the same result using interfaces
How would I code my Factory?
How can this be improved and use interfaces instead ?
//Simplified noddy example
//Client code
var controlA = ControlFactory
.Create("UserControlA") as UserControlA;
panel1.Controls.Add(ControlA);
//Factory
public class ControlFactory
{
public static BaseUserControl Create(string name)
{
switch (name)
{
case "UserControlA":
var userControlA = new UserControlA();
return userControlA;
case "UserControlB":
var userControlB = new UserControlB();
return userControlB;
}
return null;
}
}
//BaseUserControl
public partial class BaseUserControl : UserControl
{
public BaseUserControl()
{
InitializeComponent();
}
public virtual void DoSomething()
{
}
}
public partial class UserControlA : BaseUserControl
{
public UserControlA()
{
InitializeComponent();
}
public override void DoSomething()
{
//Do something here
}
}
public partial class UserControlB : BaseUserControl
{
public UserControlB()
{
InitializeComponent();
}
public override void DoSomething()
{
//Do something here
}
}
Here’s how you can do it:
using System;
using System.Windows.Forms;
using System.ComponentModel;
//Interface
public interface IControl : IComponent
{
void DoSomething();
}
//Factory
public class ControlFactory
{
public static IControl Create(string name)
{
switch (name)
{
case "UserControlA":
var userControlA = new UserControlA();
return userControlA;
case "UserControlB":
var userControlB = new UserControlB();
return userControlB;
}
return null;
}
}
//BaseUserControl
public partial class BaseUserControl : UserControl, IControl
{
public BaseUserControl()
{
InitializeComponent();
}
public virtual void DoSomething()
{
}
}
public partial class UserControlA : BaseUserControl, IControl
{
public UserControlA()
{
InitializeComponent();
}
public override void DoSomething()
{
//Do something here
}
}
public partial class UserControlB : BaseUserControl, IControl
{
public UserControlB()
{
InitializeComponent();
}
public override void DoSomething()
{
//Do something here
}
}
You can retain BaseUserControl
if you have any functionality that is common to UserControlA
and UserControlB
; otherwise, eliminate it and make the latter two derive directly from UserControl
.
You should define all members you might need to access from your derived classes within your IControl
interface. This includes any members you will inherit from UserControl
. However, you will not need to re-implement these within your concrete classes.
//Interface
public interface IControl : IComponent
{
void DoSomething();
// To be inherited from UserControl.
Size Size { get; set; }
bool Focus();
event EventHandler FontChanged;
}
If you need to add these controls to a Windows Forms application – typically as the argument to a Control.ControlCollection.Add
method call – you will need to get a Control
instance corresponding to your control. Under the current implementation, this may be achieved simply through casting; however, this needs to be insulated from the consumers of your interface, in case you decide to change the underlying implementation in the future. Thus, I would use:
//Interface
public interface IControl : IComponent
{
void DoSomething();
Control AsWindowsForms();
}
//BaseUserControl
public partial class BaseUserControl : UserControl, IControl
{
public BaseUserControl()
{
InitializeComponent();
}
public virtual void DoSomething()
{
}
public Control AsWindowsForms()
{
return this as Control;
}
}
In your client code:
var controlA = ControlFactory.Create("UserControlA").AsWindowsForms();
var controlB = ControlFactory.Create("UserControlB").AsWindowsForms();
panel1.Controls.Add(controlA);
panel1.Controls.Add(controlB);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With