Search code examples
c#formsgeneric-programmingtobject

Passing a generic <TObject> class to a form


I can't seem to find out the answer to this through searching, so here goes....

I know that I can pass Class objects generically to other classes by utilising this type of code:

public class ClsGeneric<TObject> where TObject : class
{
    public TObject GenericType { get; set; }
}

Then constructing in this way:

ClsGeneric<MyType> someName = new ClsGeneric<MyType>()

However, I have an application that requires me to open a Form and somehow pass in the generic type for use in that form. I am trying to be able to re-use this form for many different Class types.

Does anyone know if that's possible and if so how?

I've experimented a bit with the Form constructor, but to no avail.

Many thanks in advance, Dave

UPDATED: A Clarification on what the outcome I am trying to achieve is

enter image description here

UPDATED: 4th AUG, I've moved on a little further, but I offer a bounty for the solution. Here is what I have now:

interface IFormInterface
{
    DialogResult ShowDialog();
}


public class FormInterface<TObject> : SubForm, IFormInterface where TObject : class
{ }

public partial class Form1 : Form
{
    private FormController<Parent> _formController;

    public Form1()
    {
        InitializeComponent();
            _formController = new FormController<Parent>(this.btnShowSubForm, new DataController<Parent>(new MeContext()));   
    }
}

public class FormController<TObject> where TObject : class
{
    private DataController<TObject> _dataController;
    public FormController(Button btn, DataController<TObject> dataController)
    {
        _dataController = dataController;
        btn.Click += new EventHandler(btnClick);
    }

    private void btnClick(object sender, EventArgs e)
    {
        showSubForm("Something");
    }

    public void showSubForm(string className)
    {
        //I'm still stuck here because I have to tell the interface the Name of the Class "Child", I want to pass <TObject> here.
        // Want to pass in the true Class name to FormController from the MainForm only, and from then on, it's generic.

        IFormInterface f2 = new FormInterface<Child>();
        f2.ShowDialog();
    }
}

class MeContext : DbContext
{
    public MeContext() : base(@"data source=HAZEL-PC\HAZEL_SQL;initial catalog=MCL;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework") { }
    public DbSet<Parent> Child { get; set; }
}

public class DataController<TObject> where TObject : class
{
    protected DbContext _context;

    public DataController(DbContext context)
    {
        _context = context;
    }
}

public class Parent
{
    string Name { get; set; }
    bool HasChildren { get; set; }
    int Age { get; set; }
}

public class Child
{
    string Name { get; set; }
    int Age { get; set; }
}

Solution

  • I think you can add a new type argument to FormController:

    public class FormController<TParent, TChild>
      where TParent : class
      where TChild : class 
    {
        ...
    
        public void showSubForm(string className)
        {
            IFormInterface f2 = new FormInterface<TChild>();
            f2.ShowDialog();
        }
    }