
Signature
- Nicholas Paldino [.NET/C# MVP]
- mvp@spam.guard.caspershouse.com
Nicholas,
> You might want to consider making all of your types non-Generic, and
> adding a method that is called which you can set the type that the form
> uses for browsing and whatnot, something like:
>
> SetBrowseType(Type type)
My planned hiearchy looks like:
Form - net base class
Baseform - contains base routines for every form used in application:
form position save-restore etc.
BusinessForm<T> ( contains Grid<T> )
- contains common logic and controls for single linear
entity type
(Customer, Product etc). editing.
BrowseForm<T> - contains few additional buttons specific for
some entities.
So if I understand your recommendation properly, I must change type T to
Form and Grid constructor parameter. I see no reason to use SetBrowseType()
since type can be passed in constructor. Why SetBrowseType() is better than
using BrowseForm(Type t) constuctor ?
> And have a generic overload on the method as well:
>
> SetBrowseType<T>()
Why this is better than using Marc hint to create generic wrapper for
designer class:
class BrowseForm<TEntity>: BrowseForm {
public BrowseForm<TEntity>( .... ): base(typeof(TEntity), ..... ) { ...}
}
BrowseForm<TEntity> makes few usagw of type T, most usage is in grid.
So I think I must use only non-generic BrowseForm and drop generic classes
at all?
> It seems you are using the type parameter to convey type information,
> which is poor design if you don't have a non-generic alternative.
T is linear entity type (Customer, Produce, Emplyee etc) which is edited in
form in Grid.
Is it poor design only since it is not supported by Designer ?
Will creating non-generic intermediate class only to satisfy designer make
it good design ?
> I would have recommended passing the type in the constructor, but that
> would have broken designer support as well =)
Is it reasonable to create parameterless constructor only for designer
support :
class BrowseForm {
// Real constructor
public BrowseForm(Type entityToEdit, ..... ) { ...}
// Empty constructor for designer support, prevent its use in code.
public BrowseForm() { Debug.Assert(false); }
}
In this case SetBrowseType() method is not required and designer can open
form.
Unresolved issue is using Grid<T> in designer.
As I understand only way is to change this grid to non generic Grid( Type
t ) and add parameterless constructor to Grid to satisfy designer.
In this case I lose compile time checking of type parameter constraints and
must use heavy
reflection in Grid class.
Is this best solution to create generic entity editing grid whose containg
form can be designed in designer?
Or should I stop using designer and design forms manually to keep code clean
?
Andrus.
Marc Gravell - 10 Feb 2008 21:02 GMT
> Unresolved issue is using Grid<T> in designer.
> ...
> Or should I stop using designer and design forms manually to keep code clean ?
Maybe use the designer for general layout, but leave a Panel as a
placeholder for you grid; have an Initialise<T>() method with whatever
arguments and constraints you need, and just setup the grid in this
generic method - i.e.
Initialise<T>() {
Grid<T> grid = new Grid<T>();
grid.Dock = {blah}.Fill;
gridPanel.Controls.Add(grid);
// etc
}
Marc
Nicholas Paldino [.NET/C# MVP] - 11 Feb 2008 17:24 GMT
Andrus,
See inline:
> My planned hiearchy looks like:
>
[quoted text clipped - 12 lines]
> SetBrowseType() since type can be passed in constructor. Why
> SetBrowseType() is better than using BrowseForm(Type t) constuctor ?
As I mentioned, you will not have designer support if you don't have a
default constructor. Since that is the aim here, having a constructor which
takes the Type is a little bit of a waste, since you will have to add a
method which will take the Type anyways (having the default constructor
^just^ for designer support is a bad idea).
>> And have a generic overload on the method as well:
>>
[quoted text clipped - 10 lines]
> So I think I must use only non-generic BrowseForm and drop generic classes
> at all?
That could work, but it depends on how much the Grid<T> and the
BrowseForm<T> are related. If the Grid expects to access elements on the
parent for some reason, then you are adding this extra constraint that there
be this wrapper class associated with your form which could cause some more
headaches.
>> It seems you are using the type parameter to convey type information,
>> which is poor design if you don't have a non-generic alternative.
[quoted text clipped - 4 lines]
> Will creating non-generic intermediate class only to satisfy designer make
> it good design ?
I say it is poor design because it appears that the only reason you are
passing T is to get type information from T. I don't know if the type T has
any constraints on it, so I don't know if you are doing anything with T
other than reflecting on it to get specific type information (if you have
constraints, you aren't reflecting most likely, but you aren't indicating
that you do have constraints).
Having ^just^ a generic method where the type parameter is used ^solely^
for the purpose of conveying type information is bad design. You would want
an additional method which would pass an instance of Type to convey the type
information, because the code that calls your code might not always have
type information at compile time.
>> I would have recommended passing the type in the constructor, but that
>> would have broken designer support as well =)
[quoted text clipped - 12 lines]
> In this case SetBrowseType() method is not required and designer can open
> form.
I would say no, because then you are polluting your design and with the
possibility that someone could call the parameterless constructor, you put
them in a situation where the form is unusable because they can't set the
type information that they would call in the constructor.
> Unresolved issue is using Grid<T> in designer.
>
[quoted text clipped - 5 lines]
> Is this best solution to create generic entity editing grid whose containg
> form can be designed in designer?
The same issues with the Grid<T> are the ones you are facing here,
really. You need a way to convey the type information on the parent to the
Grid and make it non generic (if you want designer support).
> Or should I stop using designer and design forms manually to keep code
> clean ?
Well, that depends on what your pain threshold is. If it's a simple
form, then maybe it will work, but if it is something more complex (which I
imagine it is), then you probably are going to hurt yourself a great deal by
eliminating designer support.

Signature
- Nicholas Paldino [.NET/C# MVP]
- mvp@spam.guard.caspershouse.com
> Andrus.