Andrus,
See inline:
[quoted text, click to view] > 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 ?
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).
[quoted text, click to view] >
>> 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?
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.
[quoted text, click to view] >
>> 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 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.
[quoted text, click to view] >> 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.
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.
[quoted text, click to view] > 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?
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).
[quoted text, click to view] > 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.
--
- Nicholas Paldino [.NET/C# MVP]
- mvp@spam.guard.caspershouse.com
[quoted text, click to view] >
> Andrus.
>