I have a hierarchy system of classes :
public abstract class AModel<T,U> where T : class where U : class
{
protected IList<U> _children;
protected readonly T _parent;
protected readonly String _name;
protected readonly String _urlStr;
protected String _title;
protected AModel(T parent, String name, String urlStr)
{
_parent = parent;
_name = name;
_urlStr = urlStr;
}
...
}
I use this for 5 classes that each have 1 parent and several children for example :
public class Domain : AModel<Appellation, Bottle>
{
public Domain(Appellation pAppellation, string name, string urlStr) : base (pAppellation, name, urlStr)
{
_title = "Domaine : " + _name;
}
...
}
This is very useful for handling tree views
foreach (Domain domain in appellation.Children)
{
_domains.Add(domain);
domain.SetChildren(ReferentialDbManager.Instance.SelectBottles(domain));
...
}
Now my issue is I want to use to pass the AModel to a UserControl constructor from my tree view when :
private void OnSelectedNodeChange(object sender, TreeViewEventArgs e)
{
_selectionGroupBox.Controls.Clear();
switch (e.Node.Tag.ToString())
{
case "DOMAIN":
AModel<Appellation, Bottle> selectedDomain = ReferentialManager.Instance.FindDomain(e.Node.Text);
_selectionGroupBox.Controls.Add(new APanel(selectedDomain) { Dock = DockStyle.Fill });
break;
...
}
...
}
In the APanel I will use the fields from the base AModel class so I need to pass it like
public APanel(AModel<T, U> aObject)
{
InitializeComponent();
_titleLabel.SetTitleString(aObject.Title);
}
How do I pass the generic AModel class as a parameter ?
Thanks
Generic programming is used to describe behavior that is interchangeable between types.
To use this generic behavior in the APanel
control the compiler needs to know what types are used to construct the APanel
.
If you intend to use several types with the APanel
control then describe the APanel
as a generic type.
For a WinForms control you need to change the APanel.cs
and APanel.Designer.cs
files.
APanel.cs
:
public partial class APanel<TParent, TChild> : UserControl
where TParent: class
where TChild: class
{
public APanel(AModel<TParent, TChild> model)
{
InitializeComponent();
_titleLabel.SetTitleString(model.Title);
}
}
APanel.Designer.cs
:
partial class APanel<TParent, TChild>
{
// Change the type declaration
// leave the inside of the class alone
}
Otherwise you need to provide a complete concrete type to the constructor.
public class APanel : UserControl
{
public APanel(AModel<Appellation, Bottle> model)
{
InitializeComponent();
_titleLabel.SetTitleString(model.Title);
}
}