Gridbag : howto

Posted by jmls on 28-May-2009 08:44

I have a scenario that requires a collection of UI objects (a picture and a text line) to be presented to a user. Wrinkle is that here is an unknown and varied number of these objects (0 - 200+). Another wrinkle is that the number varies during the lifetime of the form.

In the "old ABL" interface I cheated and created a fixed size window - hence it was easy to calculate the optimum number of rows and colums and create a dynamic widget of appropriate size.

In the new .net interface, there is a requirement to resize the form. Ouch. I have played with the gridbag control and initially it seems to cope with adding a varied number of UI objects (1,20,4 etc) at startup. However, when the form resizes, the grid does not adjust the number of rows and columns, just adjusts the height/width of the UI objects.

For example, take the 4 objects (A,B,C,D) initially:

AB

CD

when I resize horizontally, if there is enough space, I would like to see

ABCD

However, what I get is

AAAAAAAAAAAAAABBBBBBBBBBBBBBB

CCCCCCCCCCCCCCDDDDDDDDDDDDDDD

(where the AAA etc represents a resize (streched) object )

Has anyone got any clues or tips on using the gridbag ?

All Replies

Posted by Peter Judge on 28-May-2009 08:59

jmls wrote:

I have a scenario that requires a collection of UI objects (a picture and a text line) to be presented to a user. Wrinkle is that here is an unknown and varied number of these objects (0 - 200+). Another wrinkle is that the number varies during the lifetime of the form.

In the "old ABL" interface I cheated and created a fixed size window - hence it was easy to calculate the optimum number of rows and colums and create a dynamic widget of appropriate size.

In the new .net interface, there is a requirement to resize the form. Ouch. I have played with the gridbag control and initially it seems to cope with adding a varied number of UI objects (1,20,4 etc) at startup. However, when the form resizes, the grid does not adjust the number of rows and columns, just adjusts the height/width of the UI objects.

For example, take the 4 objects (A,B,C,D) initially:

AB

CD

when I resize horizontally, if there is enough space, I would like to see

ABCD

However, what I get is

AAAAAAAAAAAAAABBBBBBBBBBBBBBB

CCCCCCCCCCCCCCDDDDDDDDDDDDDDD

(where the AAA etc represents a resize (streched) object )

Has anyone got any clues or tips on using the gridbag ?

There's a 'Expand to fit height' and 'expand to fit width' option on the UltraGridBagLayoutManager's SmartTag. Do those change the behaviour (although they're unchecked by default)?

It also looks like the controls that are added to the GridBag have a extender-provided set of properties which look to provide constraints on the layout: things like Anchor and Fill. I'm not sure how these interact with the control's Dock and Anchor properties, but they might be worth looking at.

-- peter

-- peter

Posted by jmls on 28-May-2009 09:06

Thanks for the reply, Peter. However, it's not the size / fill of the UI objects themselves that is the issue (they _do_ what I want), I want the gridbag itself to change the number of rows and columns.

I've also been playing with the standard ms flowpanellayout , and this actually does what I want (dynamic rows / cols) but _doesn't_ resize the contents

Posted by Peter Judge on 28-May-2009 09:16

Would the UltraFlowLayoutManager not work for this?

[edit] not by itself, it seems.

So you're looking for the flow behaviour for the dynamic moving of the cells to from AB/CD to ABC/D to ABCD (if you know what I mean), and also for those cells to resize appropriately?

-- peter

Posted by jmls on 28-May-2009 09:50

yes. Don't want much, do I ?

Posted by Peter Judge on 28-May-2009 09:59

If you use the UltraFlowLayoutManager, you can subscribe to the contained controls' Move event. At that point you can set the preferred size of the control for the flow manager, which respects it.

ultraFlowLayoutManager1:SetPreferredSize(ultraPanel4, NEW System.Drawing.Size(, )).

The trickier bit is figuring out what the width (and height too, I guess) you want is. I couldn't see an easy way of telling that a control is N of M on a row or column. An (extremely) ugly way might be to count how many moves were made and record the positions after the move, and when they're all done moving about, then figure out who's where and calculate the preferred size accordingly.

You can also mess with the HorizontalAlignment and ~Gap (and their Vertical equivalents, no doubt) to try and reduce the gaps.

I also think that it's worth having a panel which contains the stuff (picture and whatever) so that you can dock/anchor within that control; then you only need to worry about the panel in the context of the flow manager.

-- peter "harking back to the good old days of resizing in the adm2"

Posted by jmls on 04-Jun-2009 13:16

having succeeded in my quest, I find that I hate the result. Looks rubbish.

What I have been attempting to do is a cardview type thing in infragistics. Not very well !

I am trying to acheive something similar to the attached picture. Anyone been able to do something like that and are willing to share ?

I will battle on - if I succeed I will post the results here. In the meantime, please raise a glass of the good stuff and toast to my struggle against the awful mess that is the ultragrid object model

Posted by Admin on 04-Jun-2009 13:51

jmls schrieb:

having succeeded in my quest, I find that I hate the result. Looks rubbish.

What I have been attempting to do is a cardview type thing in infragistics. Not very well !

Do you have a screenshot of how far you got?

Posted by jmls on 04-Jun-2009 14:11

Yeah, but it's not pretty ...

What I am wanting to do is have the Name along the top, remove the name row (pointless) and have a picture of said agent. I want to add some other stuff (rows, etc), but I think (!) I can do that.

Posted by Håvard Danielsen on 04-Jun-2009 14:17

Did you look at the WinGrid/SamplesExplorer/frmRowLayout.cls in the samples?

This sample demonstrates the Row Layout functionality, which gives complete control of the grid layoyut. The defined layout can also be saved and loaded from external files.

The sample has a TabControl with 5 pages. The 4 first pages shows Employee grids of two types; a standard view RowLayout and a CardView RowLayout, which both are shown in two exact similar versions. The first grid of each type is built at design time with the UltraGrid designer while the second of each grid has a row layout that is created with code at runtime. The last page shows a regular grid that is using a row layout loaded from an external file.

Posted by jmls on 04-Jun-2009 14:20

crap. for some reason I don't have the source code anywhere. Off to download center I go ...

Posted by Thomas Mercer-Hursh on 04-Jun-2009 14:57

Sounds familiar from the beta ...

Posted by jmls on 05-Jun-2009 04:28

Do you know what ? I had no idea that there was such a designer for the grid. Once I found that, the rest was relatively easy !

Thanks so much to all that helped. I am very nearly there - see the attached screenshot.

It was a long struggle, but now I think I could apply the lessons to other tasks and produce much quicker results.

Thanks again.

Posted by Admin on 05-Jun-2009 05:39

Lovely!

Posted by jmls on 05-Jun-2009 06:18

Heh, don't know if that is a "lovely" as in "very nice" or a sarcastic "lovely" as in "oh my god, that's awful" ...

Anyways, another question:

I need to update the time on each record every few seconds or so. I've stored the cell in an array, and can reference it directly by a grid number:

assign TempTable.field = somevalue.

MyCell[gridnum]:refresh().

this works for all cells. Very well. Except for the currently selected record. This does not get updated until I deselect it.

Any clues ?

Posted by jmls on 06-Jun-2009 03:38

Hmmm. I've even tried to do

Ultragrid1:Rows:Refresh(RefreshRow:RefreshDisplay).

when the timer ticks, to no avail.

I wonder if there is something about the grid that is preventing this. Is there an option to make the grid read-only ?

Posted by Admin on 07-Jun-2009 12:34

jmls schrieb:

Is there an option to make the grid read-only ?

Hi Julian,

there are a number of properties you may want to check:

        ultraGrid1:DisplayLayout:Override:AllowAddNew = AllowAddNew:No.

        ultraGrid1:DisplayLayout:Override:AllowDelete = DefaultableBoolean:False.

        ultraGrid1:DisplayLayout:Override:AllowUpdate = DefaultableBoolean:False.

and for the cells:

:CellActivation = Infragistics.Win.UltraWinGrid.Activation:NoEdit .

Posted by jmls on 07-Jun-2009 13:13

What is really bizzare is that I have just tried the form on a 2003 server and the display is updated automatically as I expected. Same program on windows 7 does not. Interesting.

Posted by Admin on 07-Jun-2009 15:07

jmls schrieb:

Heh, don't know if that is a "lovely" as in "very nice" or a sarcastic "lovely" as in "oh my god, that's awful" ...

More in the form of "nice" or "not bad" :-)

Posted by Håvard Danielsen on 08-Jun-2009 08:00

jmls wrote:

Hmmm. I've even tried to do

Ultragrid1:Rows:Refresh(RefreshRow:RefreshDisplay).

when the timer ticks, to no avail.

I wonder if there is something about the grid that is preventing this. Is there an option to make the grid read-only ?

I see the same behavior when using refresh directly on the grid as in UltraGrid1:Refresh().  (Windows XP).

I can workaround the problem by refreshing the Progress bindingsource also:

  cast(ultraGrid1:DataSource,Progress.Data.BindingSource):Refresh().

or instead:

  cast(ultraGrid1:DataSource,Progress.Data.BindingSource):RefreshAll().

I suggest you report it to Support (even if it not necessarily is a bug in the ABL).

Posted by jmls on 08-Jun-2009 08:15

hdaniels wrote:

I see the same behavior when using refresh directly on the grid as in UltraGrid1:Refresh().  (Windows XP).

I can workaround the problem by refreshing the Progress bindingsource also:

  cast(ultraGrid1:DataSource,Progress.Data.BindingSource):Refresh().

or instead:

  cast(ultraGrid1:DataSource,Progress.Data.BindingSource):RefreshAll().

I suggest you report it to Support (even if it not necessarily is a bug in the ABL).

After I've added the suggestion from Mike

ultraGrid1:DisplayLayout:Override:AllowAddNew = AllowAddNew:No. 
        ultraGrid1:DisplayLayout:Override:AllowDelete = DefaultableBoolean:False.
        ultraGrid1:DisplayLayout:Override:AllowUpdate = DefaultableBoolean:False.


and some other changes, the thing has started to work. I suspect that it is something to do with the update of the cell - if there is some editing taking place, it's not going to be refreshed.

Posted by Håvard Danielsen on 08-Jun-2009 08:41

After I've added the suggestion from Mike

ultraGrid1:DisplayLayout:Override:AllowAddNew = AllowAddNew:No. 
        ultraGrid1:DisplayLayout:Override:AllowDelete = DefaultableBoolean:False.
        ultraGrid1:DisplayLayout:Override:AllowUpdate = DefaultableBoolean:False.





and some other changes, the thing has started to work. I suspect that it is something to do with the update of the cell - if there is some editing taking place, it's not going to be refreshed.


What are those other changes? (Setting those properties does not help in my sample).

What strategy to use for refresh of edited data is a challenge in a component framework, so this could possibly be expected behavior. (but your claim that it worked in a different environment suggests otherwise)

Posted by jmls on 08-Jun-2009 12:59

hdaniels wrote:

What are those other changes? (Setting those properties does not help in my sample).

What strategy to use for refresh of edited data is a challenge in a component framework, so this could possibly be expected behavior. (but your claim that it worked in a different environment suggests otherwise)

Hmm. I also added

ExitEditModeOnLeave=false

UpdateMode=OnUpdate

CausesValidation=false

in the properties of the grid

HTH

Posted by Håvard Danielsen on 10-Jun-2009 10:40

Hmm. I also added

ExitEditModeOnLeave=false

UpdateMode=OnUpdate

CausesValidation=false

in the properties of the grid

HTH

None of these seems to fix the problem in the "next" version of Progress.

I have reported this as issue OE00185963 based on my findings that all rows are refreshed if the grid is using an IList DataSource.

Posted by jmls on 22-Jun-2009 14:43

I eventually gave up on this. No matter which control I used, I ran into problems. The final straw was the huge memory leaks from DevXpress. After 30 minutes, the prowin32 app reached 400MB

However, there is some good news. I started from scratch, and rather than using a grid control, I created a user control with the picture and fields that I wanted. I then put this user control into a flowlayoutpanel control, and it works !

See the attached screenshot for an idea of how it looks.

Each "card" can be collapsed and expanded. The caption colours change based on the Agent status (user-defined colours, I hasten to add) and the cards flow around the screen when the window changes size.

I also found a way of sorting the cards based on any criteria I liked, using the SetChildIndex() method of the flowlayoutpanel

A great example of the power of user controls.

This thread is closed