I have a grid with customers and a grid with orders.
The order grid had GroupByMode:OutlookDate set on the orderDate field. Every customer has at least one order with orderDate 'today'. However, when I iterate through the customers this record is sometimes shown in the 'today' group and sometimes in the 'older' group (in which case no 'today' group is created).
It gets even weirder, since these are the groups I observe when iterating:
customer 1: Today, Three Weeks Ago, Last Month, Older (total 18 records)
customer 2: Older (contains today and last month records as well, 5 records in total).
customer 3: Older (contains today and older, 4 records in total)
customer 2: Now display the today record in it's own Today group and the other 4 records in an Older group!!!
So the behavior seems somehow to depend on the previous groups?!?
I refresh the second bindingSource by closing the query, reloading the records and opening the query again. RefreshAll() does not make a difference.
What is happening here? How can I fix it?
What's the type of the orderDate field? DATE or DATETIME?
I'm not sure whethere it's an issue, but the help says:
"
The settings that relate to dates and times should only be used with columns whose DataType is DateTime. If this property is set to a value which does not make sense for the DataType of the column, the groupings will based on a "dummy" default value whenever possible.
"
-- peter
OK I switched from DATE to DATETIME but it makes no difference.
I've tested this on a single grid with customer and order bands from sports2000 and the order records seem to end up in the right group when GroupByMode:OutlookDate is set on the orderDate field.
I have a grid with customers and a grid with orders.
Do you actually have two separate grids? or do you mean a grid with a customer band and order band?
The order grid had GroupByMode:OutlookDate set on the
orderDate field. Every customer has at least one
order with orderDate 'today'. However, when I iterate
through the customers this record is sometimes shown
in the 'today' group and sometimes in the 'older'
group (in which case no 'today' group is created).
How do you iterate through customers and how do you access the data in the iteration?
Do you actually have two separate grids? or do you
mean a grid with a customer band and order band?
Two grids.
How do you iterate through customers and how do you
access the data in the iteration?
I refresh the query of the second browse on positionChanged of the first bindingSource.
I have created and attached a simplified reproduction on the Sports2000 database that exhibits the behavior. Very weird. I am curious what you make of it.
And as always I am open to suggestions/improvements of the code!
[View:~/cfs-file.ashx/__key/communityserver-discussions-components-files/19/customer.cls:550:0]
[View:~/cfs-file.ashx/__key/communityserver-discussions-components-files/19/customerform.cls:550:0]
I have created and attached a simplified reproduction
on the Sports2000 database that exhibits the
behavior. Very weird. I am curious what you make of
it.
Changing your refresh as follows seems to correct the problem:
/* ultraGrid2:REFRESH(). */
hquer#:QUERY-OPEN().
bindingSource2:handle = ?.
bindingSource2:handle = hquer#.
/* bindingSource2:refreshAll(). */
It is possible that this is a bug. (I'll try to find out more)
And as always I am open to suggestions/improvements
of the code
Apart from the fact that there is no separation of logical and physical layers, use of inheritance for what seems to be an attempt at separation of view and presentation and that you open the query in the constructor, it looks good...
I assume most of this is due to the simplification. I am actually most puzzled by your use of inheritance. Maybe a discussion for another thread?
Changing your refresh as follows seems to correct the
problem:
hquer#:QUERY-OPEN().
bindingSource2:handle = ?.
bindingSource2:handle = hquer#.
Indeed that fixes the problem!
It is possible that this is a bug. (I'll try to find
out more)
OK let me know if you want me to report this. For now I will use this in all parent-child situations to be on the safe side.
And as always I am open to
suggestions/improvements
of the code
Apart from the fact that there is no separation of
logical and physical layers, use of inheritance for
what seems to be an attempt at separation of view and
presentation and that you open the query in the
constructor, it looks good...
I assume most of this is due to the simplification. I
am actually most puzzled by your use of inheritance.
Maybe a discussion for another thread?
Most of it is indeed simplification, except for the use of inheritance.
See http://www.psdn.com/library/thread.jspa?threadID=14608.
I like the approach and am using it since. It is not a real attempt to separate view from presentation, but is it far easier to maintain when the logic is separated from the generated code.
What do you think of that approach?
> OK let me know if you want me to report this. For now I will use this in all parent-child situations to be on the safe side.
This is a bug. I'd appreciate if you report this.
> See http://www.psdn.com/library/thread.jspa?threadID=14608
I like the approach and am using it since. It is not
a real attempt to separate view from presentation,
but is it far easier to maintain when the logic is
separated from the generated code.
What do you think of that approach?
I can certainly understand that it makes the code easier to maintain.
It is just that it looks so close to a real separation of presentation logic from view/layout...
If you simply NEW the form instead of inheriting you will have a far more flexible coupling:
- You can support multiple layout variations with the same presentation code.
- You can make the layout manage multiple controls instead of a single form if necessary.
- You can easier split the visual control into smaller controls for reuse.
- Your layout code is less likely to be bound to the form.
(It is a very common architectural problem in GUI applications that the window/form is tied to the structure of the code. This can prevent you from splitting the view into multiple windows and it can prevent you from fully utilizing MDI, explorer bars, and tabbed folders to combine separate views in a form.)
I'm not saying that composition can replace inheritance, but you can only inherit from one class, so you need to use it wisely. The navigation logic in this sample could easily be extracted into a common class that you could use for any case with similar object configuration. Since your class already inherits the form you would need to add the common behavior above the form. I guess this still works, but if you also want to add general behavior to the view, you will end up mixing layout code and logic in super classes.
I fully realize that simply NEWing the form does not provide for a true separation of presentation and view either. Taken to its full extent the presentation logic should not have any references to .NET even. It should in theory be possible to run the same ABL application in not .NET, TTY and GUI. Note that I do not for a second think it is possible to write UI logic that are portable across UIs without loosing the specific benefits each of the UIs provide. I still think there is a lot to be gained from an architecture that has such separation, but it requires more work upfront and it might not be worth it in a simple app.
This is a bug. I'd appreciate if you report this.
W/R: W903100055
bug# OE00182092
What do you think of that approach?
I can certainly understand that it makes the code
easier to maintain.
It is just that it looks so close to a real
separation of presentation logic from view/layout...
So this seems like a good and practical start then.
If you simply NEW the form instead of inheriting you
will have a far more flexible coupling:
- You can support multiple layout variations with the
same presentation code.
- You can make the layout manage multiple controls
instead of a single form if necessary.
- You can easier split the visual control into
smaller controls for reuse.
- Your layout code is less likely to be bound to the
form.
Could you modify this example accordingly and repost it?
So this seems like a good and practical start then.
It does.
Could you modify this example accordingly and repost it?
By some weird incident my 10.2B version of the editor got into a hang when I used inheritance... (relax, it will be fixed before we ship), so I already did do this change.
Note:
1. I have lower cased the original code also...
2. I'm using a runner (since I said not to load data in the constructor. You do not need this, you can make it work by calling init and showandwait from the customer.cls constructor)
3. the data classes are in a data folder. I split it in two also.
4. the files are in an additional adewrk directory in the zip file. It's not referenced, so it can be removed.
This exercise raises several issues:
As soon as you do this change you realize that you probably want a better naming of some of the stuff. bindingSource1 and bindingSource2 are names that should be private or protected...
Even with good names, it is questionable to expose these. It is probably better to encapsulate the usage, for example in a bindCustomer and bindOrder methods or something similar. ( This would move us towards a more complete separation of UI and logic also, I think)
This "problem" of course applies to other controls that you need to control from the logic. It might be challenging and time consuming to keep the UI and logic properly separated, but I think the benefits can be huge in the long run if you manage to do this.
I would probably move the event subscription into the view (generated form) and keep the event handler there and make the handler call CustomerChanged in the UI logic class. But this would require the view to know about the handler and thus require more changes and it would also move some coding back into the View, which is what you tried to avoid. I think it is possible to implement some eventing that is both more generic and that does not require the view to know the presenter/ui logic (or uses an interface). This is certainly an area that one would need to spend some time on. There are many events you always want to subscribe to, in particular for bindingSource, so it should not be necessary to define them each time.
This is by no means a final example. Let me quote Greg Higgins from the other thread: "It's still early yet to be promoting a specific best practice."
Message was edited by:
adwrk in zip
Havard Danielsen
[View:~/cfs-file.ashx/__key/communityserver-discussions-components-files/19/groupby.zip:550:0]
Hi Harvard,
I don't believe it's an either or. Your MVC pattern and the "simulated partial classes" play very well together. In fact, I consider the simulated partial classes a single unit, a single class.
It is just that it looks so close to a real
separation of presentation logic from view/layout...
If you simply NEW the form instead of inheriting you
will have a far more flexible coupling:
I never NEW the Designer class. I always NEW the class that inherits from the Designer Class and contains the "low level" event logic - so the code that is really tied to the fact if I'm using a MS toolbar or an Infragistics Toolbar or a button click or a leave event to start certain action.
- You can support multiple layout variations with the
same presentation code.
You will not be able to share all event handlers when re-using the controller with multiple views. So there are always event handlers that are tied to a particular design. Even without changing the technology or display device.
- You can make the layout manage multiple controls
instead of a single form if necessary.
- You can easier split the visual control into
smaller controls for reuse.
Works with "partial user control classes" or inherited Controls as well. (At least in 10.2A )
- Your layout code is less likely to be bound to the
form.
(It is a very common architectural problem in GUI
applications that the window/form is tied to the
structure of the code. This can prevent you from
splitting the view into multiple windows and it can
prevent you from fully utilizing MDI, explorer bars,
and tabbed folders to combine separate views in a
form.)
That's where UserControls come in handy.
I fully realize that simply NEWing the form does not
provide for a true separation of presentation and
view either. Taken to its full extent the
presentation logic should not have any references to
.NET even. It should in theory be possible to run the
That's where an Interface for the Presentation logic can be used. The UI part (my classes inheriting from the Designed class) use event handlers and call the presentation logic using an Interface. This way you can replace the UI and the presentation logic (or both).
So in short, I fully share your view about structuring a (complex) UI screen in the OO world. The partial classes should simply help to manage the source code (in C# it's more like an include file than a real separated class). The ability to version control (and compare changes) to the Design and the low level event logic is something that I don't wanna miss. It's not something I have to use in my model - just an option.
1. I have lower cased the original code also...
I really don't want to sound negative or insulting at all - and I appreciate any sample or demo code released by PSC - but when Progress (as a company not anybody working for Progress) releases ABL source code of any kind, it should either be all upper or lower cased.
If the recent tendency goes to lower cased keywords, somebody should log a bug that the documentation or online help needs to be changed as well. (I won't do so, because I'm so used to uppercased keywords).
It's a bit anoying when looking at Dynamics or ADM2 source code and by the fact if a line of source code is all upper cased or lower cased you can see if it was changed just recently or more than 2 years ago.
> I don't believe it's an either or. Your MVC pattern and the "simulated partial classes" play very well together. In fact, I consider the simulated partial classes a single unit, a single class.
That makes sense, but then it is a view and should not have any UI logic.
> You will not be able to share all event handlers when re-using the controller with multiple views. So there are always event handlers that are tied to a particular design. Even without changing the technology or display device.
Yes, there are event handlers tied to the control, which belongs in the view (in the extended form in your case). You should share logical events though.
You should share logical events though.
Absolutely. Those of us still on 10.2A need to use event methods in Interfaces.
In my opinion, one of the most important principles when defining code standards is that one should be able to improve the standard without having to fix current code up to the standard.
Without such a rule coding standards will rarely improve.
Agreed. So I assume, that lower cased is the new PSC coding standard. Are those standards accessible for the public? So that others can improve as well
Message was edited by:
Mike Fechner
>Are those standards accessible for
the public? So that others can improve as well
You know, I thought I heard a can of worms being opened earlier
-- peter
Are you sure it isn't a case of PSC catching up to the public ...
Does this mean that future versions of OEA will have lower case templates?
Does this mean that future versions of OEA will have
lower case templates?
Not that I know of. If you want that .... wait for it .... log a bug :). I think that smarter behaviour would be to automatically apply your casing preference to a newly-created form, class etc, so that it wouldn't matter what case the template was in. And then OEA wouldn't need to ship 2+ versions* of each of the templates.
-- peter
All caps, all lower case, some funky Enterprisey mixture etc
Are you sure it isn't a case of PSC catching up to
the public ...
I don't think so. There is a large enough public that still prefers upper cased key words. I'm one of them.
Does this mean that future versions of OEA will have
lower case templates?
I'd say it's all one or the other: Docs, online help, training materials, templates, samples etc. Either that all get's updated or the company should stick with UPPER cased key words.
So maybe if there are no new features for a release past 10.2B, lower casing the toolkit may be a task.
Time for a coding standards thread?
And not to forget TABs vs. SPACEs.
Time for a coding standards thread?
I know it's Friday 13th, but I don't believe that the tradition is to actively seek harm to yourself
-- peter
I know it's Friday 13th, but I don't believe that the
tradition is to actively seek harm to yourself
That's no way to talk about a good, relaxing, intractable argument!
I never NEW the Designer class. I always NEW the
class that inherits from the Designer Class and
contains the "low level" event logic - so the code
that is really tied to the fact if I'm using a MS
toolbar or an Infragistics Toolbar or a button click
or a leave event to start certain action.
- You can support multiple layout variations with
the
same presentation code.
You will not be able to share all event handlers when
re-using the controller with multiple views. So there
are always event handlers that are tied to a
particular design. Even without changing the
technology or display device.
- You can make the layout manage multiple controls
instead of a single form if necessary.
- You can easier split the visual control into
smaller controls for reuse.
Works with "partial user control classes" or
inherited Controls as well. (At least in 10.2A )
- Your layout code is less likely to be bound to
the
form.
(It is a very common architectural problem in GUI
applications that the window/form is tied to the
structure of the code. This can prevent you from
splitting the view into multiple windows and it
can
prevent you from fully utilizing MDI, explorer
bars,
and tabbed folders to combine separate views in a
form.)
That's where UserControls come in handy.
I fully realize that simply NEWing the form does
not
provide for a true separation of presentation and
view either. Taken to its full extent the
presentation logic should not have any references
to
.NET even. It should in theory be possible to run
the
That's where an Interface for the Presentation logic
can be used. The UI part (my classes inheriting from
the Designed class) use event handlers and call the
presentation logic using an Interface. This way you
can replace the UI and the presentation logic (or
both).
So in short, I fully share your view about
structuring a (complex) UI screen in the OO world.
The partial classes should simply help to manage the
source code (in C# it's more like an include file
than a real separated class). The ability to version
control (and compare changes) to the Design and the
low level event logic is something that I don't wanna
miss. It's not something I have to use in my model -
just an option.
I'm attaching the code with changes according to Mike's clarification.
I added a customerview.cls that inherits the form as the original, but kept the UI logic in the customer.cls
I added an interface for the event handling from view to presenter. (very simplified)
This is still an experimental exercise and in no way a complete MVP sample, but it illustrates split of ui and layout as well as split of generated and manual view code.
[View:~/cfs-file.ashx/__key/communityserver-discussions-components-files/19/example.zip:550:0]