Reputation: 4413
I have the following Interface Declaration:
public interface IBasePresenter
{
void Run();
void ShowDialog<T, M>(T t, M m ) where T : UserControl where M : Form, ISomeInterface<SomeType>;
}
The ShowDialog() is basically a method that will show a modal dialog box to the user. Where 'T' is the parent Form and M is the unique dialog to show. M of which there are multiple different types! Hence the reason to choose a generic method!
A couple of ways I think this method could be used:
Presenter.ShowDialog(this, typeof(Form1)); // FigA
Or
Presenter.ShowDialog(this, new Form1()); // FigB
Based upon Fig A or B, what exactly will a sample ShowDialog() method implementation look like?
My questions stems from trying to figure how the generic parameter 'M' is instantiated inside of a ShowDialog() method implementation.
Upvotes: 3
Views: 345
Reputation: 4413
Below is an slightly updated version of the interface method:
void ShowDialog<TParentForm, TDialogForm, TModel, TEntity>(TParentForm t, TDialogForm m, Action callback)
where TParentForm : UserControl
where TModel : class, IModel<TEntity>, new()
where TDialogForm : Form, IEditableItem<TEntity>, new();
I made some assumptions on the previous version so during my testing and refinement phase the method signature has changed. It's still more or a less a en educational exercise for me so I still wanted to know how to pull it off rather than simple chose the easy way out.
A sample implementation of the method:
public void ShowDialog<TParentForm, TDialogForm, TModel, TEntity>(TParentForm t, TDialogForm m, Action callback)
where TParentForm : UserControl
where TModel : class, IModel<TEntity>, new()
where TDialogForm : Form, IEditableItem<TEntity>, new()
{
using (var dialogToShow = new TDialogForm())
{
dialogToShow.StartPosition = FormStartPosition.CenterScreen;
dialogToShow.FormBorderStyle = FormBorderStyle.FixedSingle;
dialogToShow.Model = new TModel();
// 2. show the new user control/form to the user.
var result = dialogToShow.ShowDialog(t);
// 3. handle the dialog result returned and update the UI appropriately.
if (result == DialogResult.OK)
{
// print status label.
callback.Invoke();
}
}
}
I am not entirely sure why the 'TDialogForm m' parameter is still in there as it does not seem to be used anywhere.
How to use the method:
private void BtnAddNewServiceClick(object sender, EventArgs e)
{
Presenter.ShowDialog<ServerRolesControl, AddNewServiceForm, ServiceModel, Role>(this, new AddNewServiceForm(), SetAddedRolesLabel);
}
private void BtnViewAllServicesClick(object sender, EventArgs e)
{
Presenter.ShowDialog<ServerRolesControl, ViewRolesForm, ServiceModel, Role>(this, new ViewRolesForm(), SetDeletedRolesLabel);
}
I should update the interface method but it was so much pain getting it to work I would rather leave it alone now =).
Upvotes: 0
Reputation: 6660
You could change the generic method signature as follows:
public void ShowDialog<T>() where T : Form, new() {
using(var dialog = new T()){
dialog.ShowDialog();
}
}
and then the call:
ShowDialog<MyCoolDialog>();
would result in the mtheod creating (not inferring this time ;)) a new instance of the form and showing it in a modal way.
Upvotes: 2
Reputation: 727067
You cannot use the Fig A
way because typeof(Form1)
is a System.Type
, not a Form
; the code will not compile unless there is an overload that takes a second parameter of type System.Type
.
how the generic parameter 'M' is instantiated inside of a ShowDialog() method implementation?
It is not "instantiated" it is "inferred:. You provided the instance already; the compiler infers the type from the invocation.
Upvotes: 4
Reputation: 1064184
At a guess:
m.Controls.Add(t);
m.ShowDialog();
However, frankly I'm not sure this utility method adds much useful, and it could just as well be non-generic (void ShowDialog(Control t, Form m)
). It could perhaps be more useful if using the : new()
constraint, which would also avoid the risk of using the same control instance on multiple forms (illegal). But as I say: frankly I wouldn't bother with this method until it had demonstrated some non-trivial usefulness. And if I did keep it, I'd rename the parameters to be more illuminating; none of M, m, T, t tell me what they mean.
Upvotes: 5