Our minds cannot repel logic of that magnitude!
Flex AdvancedDataGrid/DataGrid Optimizer
Okay, this one is for all the fellow ActionScript/Flex programmers out there. Have you ever dumped data into a DataGrid or an AdvancedDataGrid only to have your column widths be completely off, or even your row heights be off? Don’t you hate it when the contents of your grid’s cells are cut short? Well here is an easy function that resizes your columns and your grid’s rowHeight so that your data is completely displayed (provided your grid is large enough, of course).
This function takes into account both width and height, and allows you to specify padding for the width and height. It analyzes the measured display height and width of each data cell and assigns the largest values for width to each column, and the largest value for height to the DataGrid/AdvancedDataGrid’s row height. Simply pass it the DataGrid/AdvancedDataGrid you want to optimize width and height for, and the padding values, should you want to put in padding. I call this the xGrid Optimizicator™. Hope it comes in useful!
import mx.controls.AdvancedDataGrid; import mx.controls.advancedDataGridClasses.*; import mx.controls.DataGrid; import mx.controls.dataGridClasses.*; private function optimizeDataGrid(dg:Object,widthPadding:uint = 0,heightPadding:uint = 0):void { if ((!dg is AdvancedDataGrid) && (!dg is DataGrid)) return; var col:uint; var tf:TextFormat; var renderer:UITextField; var widths:Array = new Array(dg.columnCount); var height:uint = 0; var dgCol:Object; if (dg.columnCount > 0 && dg.dataProvider != null) { for (col = 0; col < dg.columnCount; ++col) widths[col] = -1; for each (var item:Object in dg.dataProvider) { for (col = 0; col < dg.columnCount; ++col) { if (dg is AdvancedDataGrid) renderer = new AdvancedDataGridItemRenderer(); else renderer = new DataGridItemRenderer(); dg.addChild(renderer); dgCol = dg.columns[col]; renderer.text = dgCol.itemToLabel(item); widths[col] = Math.max(renderer.measuredWidth, widths[col]); height = Math.max(renderer.measuredHeight, height); dg.removeChild(renderer); } } for (col = 0; col < dg.columnCount; ++col) { // Added to take into account header text - thanks modtodd! renderer = new DataGridItemRenderer(); dg.addChild(renderer); renderer.text = dg.columns[col].headerText; widths[col] = Math.max(renderer.measuredWidth,widths[col]); dg.removeChild(renderer); if (widths[col] != -1) dg.columns[col].width = widths[col] + widthPadding; } if (height != 0) dg.rowHeight = height + heightPadding; } }
| Print article | This entry was posted by JonnyFunFun on 11 Nov 2008 at 11:22, and is filed under Flex/ActionScript, Programming. Follow any responses to this post through RSS 2.0. You can leave a response or trackback from your own site. |



















































about 12 months ago
Great post….
I have one question in regards to this code. The resize works great but does not take the column name width into account only the data. Is there a way to include the column headerText in the calculation so either the widest data value or the header name would determine the width of the column?
Thank You
Todd
about 12 months ago
@modtodd –
The function could easily be changed to accommodate the column header. Where we loop through the columns, after the last for line, add the following:
I’ve updated the post to include the addition. Thanks for your input! Let me know how it works out for you!
about 10 months ago
Hi Jonny,
I tried out your function and it didn’t work at all!!! It chose values for each column width that totally cut off all my text. Any idea what could be wrong? I have a some columns that have non-text item-renderers. They use buttons. Is that an issue?
Can I email you a screenshot?
about 9 months ago
Hey perkindiafrawl, welcome to the site! Feel free to e-mail me a screenshot if you would like.
If you are using non-text item-renders like buttons, then you are going to have to add a special case to the function to set a static width to those columns – or we’ll have to rewrite the function to use something other than a UITextField for the renderer we use to get the measuredWidth.
I suppose I could revisit this function and spiff it up to use the measuredWidth of the itemRenderer if a column uses a renderer. I’ll add this to my list of to-do’s for the week and see if I can pound out a function.
about 8 months ago
This looks promising for a project i am working on. I am trying to use this code but am getting errors, i attached screencaps here. [removed for privacy]
Was wondering if you had any suggestions or do you have a working demo somewhere so that i can see if this will be useful for my dev team to incorporate?
Thanks
Rich
about 8 months ago
Hello Rich! Glad my code can help you! The problem that you’re having is actually quite simple and it was my fault. For some reason all the ampersands in the code got replaced with the HTML-friendly amp code. All you need to do is replace the HTML-friendly codes with proper ampersands, less-than signs, and greater-than signs. I updated the post above to not have the ampersands and comparison signs in their HTML-friendly format. You can either replace them yourself manually, or just re-copy-paste the code block into your code. Hope that helps! If you need more help please feel free to ask!