Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 10 of 19 total
Thread Moving from Static to Dynamic Datamodules
Wed, Dec 30 2015 12:23 AMPermanent Link

Adam H.

Hi All,

I hope you guys had an enjoyable Christmas.

Since they became available (in D3 I think it was), I've always used
DataModules to store my datacomponents on, and have linked my controls
from a form to the datamodule at designtime.

Each form has it's own corresponding datamodule to which it relates to.
In some rare instances a datamodule may be shared between a few forms -
but that's normally an exception rather than the rule.

I'm coming to a situation where I would like to start using datamodules
as a variable declared on the form itself. This will allow me to have
multiple instances of that form, where each form has it's own datamodule
so I don't have to worry about conflicts / sharing resources.

What I was wondering is whether or not there is a best practice approach
to this? In particular, how should I link my controls to the relevant
datasources and datasets at designtime when it's going to be declared as
a variable?

I have quite a number of controls and grids, which I like to 'setup' at
design time, so I'm hoping to avoid having to programatically allocate
every single datasource and datafield, widths for columns in grids, etc.

Just wondering if there's anything that's been introduced into Delphi
that I've missed along the way that makes this a breeze?

Cheers

Adam.
Wed, Dec 30 2015 5:06 AMPermanent Link

Adam Brett

Orixa Systems

Hi Adam,

Happy new year by the way!

Newer versions of Delphi have a very whizzy set of new components called "Live Bindings" I have seen these demoed by a number of Delphi guru-types but I have never adopted or used them outside of a bit of playing around.

There are good demo videos on the EMB website showing how to use them and you may find them brilliant. I think they are intended to provide the kind of function you describe, enabling good visually based RAD-style development at design-time.

I would give yourself a couple of "days off" to try to get to grips with them though ... there is definitely a learning curve!

I always instantiate datasource and dataset components in code on a form object. Obviously this means I can't do RAD GUI design, but I find it extremely easy to debug and maintain. I tend to use Query components so I can control field-lists through SQL (and change it on the fly). Things like field-widths I control with INI settings, again so that these are controlled outside the EXE. I prefer it that way.

This makes tools like the Live Bindings components less useful for me. I would be curious to hear whether any others in the Elevate community use Live Bindings.

Good luck with this. I would be happy to pass some example code of my way of working if you were interested.

Adam
Wed, Dec 30 2015 7:27 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

Adam


First point is I can't answer your question since I'm still on D2006.

However, just a bit of gibbering since its interesting in how people go in different ways.

I used to do pretty much what you're aiming at (I think that was back with the BDE). I used to create the datamodules in the IDE but exclude from the auto-create list and create an instance as needed from the form. I moved from that to a two massive datamodules (one for use and one for lookups) but that gave problems keeping tables ate the right current record for the form showing. I now have two datamodules (one for the engine, session, databases & a general imagelist plus a few queries & stringstores, the second for lookup tables), everything else lives on the form, arranged to not obscure the visual components.

I went down that route since I found it easier to maintain things when (almost) everything for a specific form was there when I opened the form in the IDE.

Roy Lambert
Wed, Dec 30 2015 5:22 PMPermanent Link

Adam H.

Hi Adam,

Happy new year to you too! Smile

Thanks for your reply. I'm vaguely familiar with Live Bindings. I
thought that these were more for binding any component's property to a
database, I'm struggling to see how they would work with dynamically
created datamodules though.

It may be that I just have to store my datasources on my forms instead
of on the datamodules so I can redirect the links when I create the
datamodule, but I wasn't sure if there was a 'more correct' method in
doing this.

Thanks again for your reply

Best Regards

Adam.



On 30/12/2015 9:06 PM, Adam Brett wrote:
> Hi Adam,
>
> Happy new year by the way!
>
> Newer versions of Delphi have a very whizzy set of new components called "Live Bindings" I have seen these demoed by a number of Delphi guru-types but I have never adopted or used them outside of a bit of playing around.
>
> There are good demo videos on the EMB website showing how to use them and you may find them brilliant. I think they are intended to provide the kind of function you describe, enabling good visually based RAD-style development at design-time.
>
> I would give yourself a couple of "days off" to try to get to grips with them though ... there is definitely a learning curve!
>
> I always instantiate datasource and dataset components in code on a form object. Obviously this means I can't do RAD GUI design, but I find it extremely easy to debug and maintain. I tend to use Query components so I can control field-lists through SQL (and change it on the fly). Things like field-widths I control with INI settings, again so that these are controlled outside the EXE. I prefer it that way.
>
> This makes tools like the Live Bindings components less useful for me. I would be curious to hear whether any others in the Elevate community use Live Bindings.
>
> Good luck with this. I would be happy to pass some example code of my way of working if you were interested.
>
> Adam
>
Wed, Dec 30 2015 5:27 PMPermanent Link

Adam H.

Hi Roy,

Thanks for your reply. I'm not sure that using less datamodules will be
a good idea for me. I've just checked and this particular project
currently has 91 datamodules in it. (Excluding data components on forms
that run reports which is another 258 units again. Wink

As I just replied to Adam, the only way I can see of achieving what I
want at the moment is to have the datasources on the form, and link
those at runtime to the datamodule variable.

ie:

procedure CreateMyForm;
var
 fm : TMyForm;
 dm : TMyDataModule;
begin
 DM := TMyDataModule.create;
 FM := TMyForm.create;
 FM.Mydatasource1.dataset := DM.MyDataSet1;
 FM.Mydatasource2.dataset := DM.MyDataSet2;
 FM.Mydatasource3.dataset := DM.MyDataSet3;
 fm.show;
end;

This would allow me to create unlimited forms with linked datamodules
without them conflicting with each other. However with so many lookup
components on the datamodules, etc - there's going to be a lot of code
to redirect even just the datasources. I was hoping there might be an
easier option, but maybe there isn't.

Best Regards

Adam.


> Adam
>
>
> First point is I can't answer your question since I'm still on D2006.
>
> However, just a bit of gibbering since its interesting in how people go in different ways.
>
> I used to do pretty much what you're aiming at (I think that was back with the BDE). I used to create the datamodules in the IDE but exclude from the auto-create list and create an instance as needed from the form. I moved from that to a two massive datamodules (one for use and one for lookups) but that gave problems keeping tables ate the right current record for the form showing. I now have two datamodules (one for the engine, session, databases & a general imagelist plus a few queries & stringstores, the second for lookup tables), everything else lives on the form, arranged to not obscure the visual components.
>
> I went down that route since I found it easier to maintain things when (almost) everything for a specific form was there when I opened the form in the IDE.
>
> Roy Lambert
>
Wed, Dec 30 2015 5:34 PMPermanent Link

Raul

Team Elevate Team Elevate

<<
I'm coming to a situation where I would like to start using datamodules
as a variable declared on the form itself. This will allow me to have
multiple instances of that form, where each form has it's own datamodule
so I don't have to worry about conflicts / sharing resources.

What I was wondering is whether or not there is a best practice approach
to this? In particular, how should I link my controls to the relevant
datasources and datasets at designtime when it's going to be declared as
a variable?
>>

I don't think there is a best way - we mostly use forms with datasources to handle design time linking.

And then in our case datamodules are part of business logic (either form or thread) - sometimes the same form could have multiple datamodules as well.

We reuse the forms heavily in various areas of our app (standalone and embedded)  and in some cases even across different apps (part of same product suite) so in our case the datamodule then provides data dynamically to datasource on form.

Raul
Thu, Dec 31 2015 4:07 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

Adam


Out of interest why are you trying to achieve this?

Back in the BDE days one of the drivers for me was to limit then number of handles being used but with the move to DBISAM that was no longer a limiting factor.

Roy Lambert
Thu, Dec 31 2015 6:26 AMPermanent Link

Adam Brett

Orixa Systems

Adam H,

I think you are right. Live Bindings are primarily for mapping your data-set components across to visual components (I think) I don't believe they replace datamodules as such. However I thought their purpose was, to some extent, to simplify management of this process, which seemed to be part of the problem you are trying to solve.

It sounds to me as though quite a lot of your complexity is in the look-ups. It might be worth trying to refactor just this portion of the problem. All my lookups are components I have written which manage themselves. The components have private dataset and datasource properties, and public fields to set SQL to generate the lookup lists.

This means all the hundreds of lookup lists don't need any data-module type source code, which is a good simplification.

Adam.
Thu, Dec 31 2015 5:59 PMPermanent Link

Adam H.

Hi Roy,

> Out of interest why are you trying to achieve this?
>
> Back in the BDE days one of the drivers for me was to limit then number of handles being used but with the move to DBISAM that was no longer a limiting factor.

In the past, I've limited users to have one detailed record screen open
at a time. (ie, one invoice at a time) such as:

procedure ShowInvoice(InvNo : Integer);
begin
Application.createform(TfmInvoice, fmInvoice);
fmInvoice.LocateInvoice(InvNo);
fmInvoice.showmodal;
fmInvoice.free;
end;

I know that this isn't necessarily the best practice as it refers to the
global form and datamodule references which means I can only have one
instance at a time but this hasn't been an issue - so I've just used
what I've been doing since Datamodules first came out. (D3 I think it
was Smile).

I was looking at changing this to something along the lines of

procedure ShowInvoice(InvNo : Integer);
var
fmInv : TFmInvoice;
begin
Application.createform(TfmInvoice, fmInv);
fmInv.LocateInvoice(InvNo);
fmInv.Showmodal;
fmInv.Free;
end;

By doing this, the user can call up and show multiple invoice forms at
the same time. It's my understanding that this is a better approach, as
each invoice form is isolated from each other and owned by an
independent variable.

While this hasn't been too important with what I've done in the past for
desktop applications - as I move towards multiple sessions (whether that
be threads or look at doing web development) - I'm going to need to be
able to create multiple instances for each session, thus my original way
of doing things will no longer be appropriate.

The above is simple, because there is no datamodule involved. However in
my real world applications, each form has it's corresponding datamodule
- which everything is linked at designtime.

ie:

procedure ShowInvoice(InvNo : Integer);
begin
Application.createform(TdmInvoice, dmInvoice);
Application.createform(TfmInvoice, fmInvoice);
fmInvoice.LocateInvoice(InvNo);
fmInvoice.showmodal;
fmInvoice.free;
dmInvoice.free;
end;


If I want to change this so I use the dynamic instance approach in my
2nd example above, I hit the problem where each child on fmInv will be
linked statically to dmInvoice, and not the variable dmInv.

At this stage I see only two real options in doing this:

1) Use script to re-link all components and lookups to the new
references on the dynamic form.

ie:

procedure ShowInvoice(InvNo : Integer);
var
fmInv : TFmInvoice;
dmInv : TdmInvoice;
begin
Application.createform(TdmInvoice, dmInv);
Application.createform(TfmInvoice, fmInv);

fmInv.Mycomponent1.datasource := dmInv.MainDS1;
fmInv.Mycomponent1.Lookupdatasource := dmInv.LookupDS1;

fmInv.Mycomponent2.datasource := dmInv.MainDS1;
fmInv.Mycomponent1.Lookupdatasource := dmInv.LookupDS2;

fmInv.Mycomponent3.datasource := dmInv.Datasource1;
fmInv.Mycomponent1.Lookupdatasource := dmInv.Datasource2;


.... etc

fmInv.LocateInvoice(InvNo);
fmInv.Showmodal;
fmInv.Free;
dmInv.Free;
end;



2) or have Datasources on the form, and relink just the datasources.

ie:

procedure ShowInvoice(InvNo : Integer);
var
fmInv : TFmInvoice;
dmInv : TdmInvoice;
begin
Application.createform(TdmInvoice, dmInv);
Application.createform(TfmInvoice, fmInv);

fmInv.MainDS1.dataset := dmInv.Dataset1;
fmInv.LookupDS1.dataset := dmInv.LookupDataset1;
fmInv.LookupDS2.dataset := dmInv.LookupDataset2;

... etc

fmInv.LocateInvoice(InvNo);
fmInv.Showmodal;
fmInv.Free;
dmInv.Free;
end;


Both of these ways seem like a lot of extra work. I'm wondering if I'm
missing something - and whether there is a simpler way (short of
dropping the use of Datamodules altogether and throwing all the datasets
and sources on the form).

Happy new year mate! Smile

Adam.
Fri, Jan 1 2016 4:53 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

Adam


Personally I'd do what you hate the idea of - dump everything on the form.

I had a brilliant idea, and as I was typing it up I suddenly realised it wouldn't work Frown

However, a question. Is the lookup table / component used for displaying the value or just obtaining it and assigning it to the invoice?

Anything else you can do will involve more work. Depending on the lookup components I'd be very tempted to subclass them, create the necessary table/datasource when a lookup is requested and then release then after (or keep there for the next use). Do that and you can probably throw away the lookup datamodules.

I can't help if its something like DevEx but if its bog standard delphi I'll be happy to do so.


Roy Lambert
Page 1 of 2Next Page »
Jump to Page:  1 2
Image