Login ProductsSalesSupportDownloadsAbout |
Home » Technical Support » ElevateDB Technical Support » Support Forums » ElevateDB General » View Thread |
Messages 1 to 10 of 19 total |
Moving from Static to Dynamic Datamodules |
Wed, Dec 30 2015 12:23 AM | Permanent 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 AM | Permanent 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 AM | Permanent Link |
Roy Lambert NLH Associates 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 PM | Permanent Link |
Adam H. | Hi Adam,
Happy new year to you too! 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 PM | Permanent 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. 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 PM | Permanent Link |
Raul 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 AM | Permanent Link |
Roy Lambert NLH Associates 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 AM | Permanent 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 PM | Permanent 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 ). 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! Adam. |
Fri, Jan 1 2016 4:53 AM | Permanent Link |
Roy Lambert NLH Associates 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 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 2 | Next Page » | |
Jump to Page: 1 2 |
This web page was last updated on Monday, May 6, 2024 at 03:23 PM | Privacy PolicySite Map © 2024 Elevate Software, Inc. All Rights Reserved Questions or comments ? E-mail us at info@elevatesoft.com |