<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>gruchalski.com &#187; stackoverflow</title>
	<atom:link href="http://gruchalski.com/category/stackoverflow/feed/" rel="self" type="application/rss+xml" />
	<link>http://gruchalski.com</link>
	<description>confessions of a ria developer</description>
	<lastBuildDate>Sat, 08 May 2010 16:43:16 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Flex DataGridColumn width set to the longest value of that column</title>
		<link>http://gruchalski.com/2009/06/16/flex-datagridcolumn-width-set-to-the-longest-value-in-that-column/</link>
		<comments>http://gruchalski.com/2009/06/16/flex-datagridcolumn-width-set-to-the-longest-value-in-that-column/#comments</comments>
		<pubDate>Tue, 16 Jun 2009 23:17:23 +0000</pubDate>
		<dc:creator>radekg</dc:creator>
				<category><![CDATA[Adobe Flex/AIR]]></category>
		<category><![CDATA[stackoverflow]]></category>

		<guid isPermaLink="false">http://gruchalski.com/?p=312</guid>
		<description><![CDATA[There was an interesting question on stackoverflow.com today. Some unnamed user asked: Can we change the width of the datagrid column dynamically by clicking on the border of the column in order to display the complete string which is too long to be displayed and needs to be scrolled ? If so, How ?Also, how [...]]]></description>
			<content:encoded><![CDATA[<p>There was an interesting question on <em>stackoverflow.com</em> today. Some unnamed user asked:</p>
<blockquote><p>Can we change the width of the datagrid column dynamically by clicking on the border of the column in order to display the complete string which is too long to be displayed and needs to be scrolled ? If so, How ?<br/><br/>Also, how can we ensure that the column width changes dynamically based on the number of characters / length of string; since many a times the data is too long to be displayed. Can we set the column width to take the length of data into consideration before displaying onto the datagrid ?</p></blockquote>
<p>It looked like a cool practice so I thought I would give it a go. This is what I came up, it doesn&#8217;t resize columns on double click but rather automatically when data provider is set/updated.</p>
<pre>[sourcecode lang="as3"]
 <?xml version="1.0" encoding="utf-8"?>
 <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
  creationComplete="onComplete();">

  <mx:Script>
   <![CDATA[
    // imports:
    import mx.events.FlexEvent;
    import mx.core.UIComponent;
    import mx.controls.dataGridClasses.DataGridColumn;
    import mx.controls.Text;
    import mx.utils.ObjectUtil;
    import mx.controls.Label;
    import mx.collections.ArrayCollection;
    // data provider:
    [Bindable] private var dp:ArrayCollection = new ArrayCollection();

    private function onComplete():void {
     // populate data provider here
     // to avoid calcMaxLengths execution when the app is created:
     dp = new ArrayCollection(
      [
       { col1: "Short", col2: "Other column 1" },
       { col1: "Some long string", col2: "Other column 2" },
       { col1: "Short", col2: "Other column 3" },
       { col1: "Short", col2: "Other column 4" },
       { col1: "The longest value in this column", col2: "Other column 5" },
       { col1: "Short", col2: "Other column 6" },
       { col1: "Short", col2: "Other column 7" }
      ]
     );
    }

    // this is going to be executed whenever the data provider changes:
    [Bindable("dataChange")]
    private function calcMaxLengths(input:ArrayCollection):ArrayCollection {
     // if there are items in the DP:
     if ( input.length > 0 ) {
      // and no SPECIAL child exists:
      if ( getChildByName("$someTempUICToRemoveAfterFinished") == null ) {
       // create new SPECIAL child
       // this is required to call measureText
       // if you use custom data grid item renderer
       // then create instance of it instead of UIComponent:
       var uic:UIComponent = new UIComponent();
       // do not show and do not mess with the sizes:
       uic.includeInLayout = false;
       uic.visible = false;
       // name it to leverage get getChildByName method:
       uic.name = "$someTempUICToRemoveAfterFinished";
       // add event listener:
       uic.addEventListener(FlexEvent.CREATION_COMPLETE, onTempUICCreated);
       // add to parent:
       addChild(uic);
      }
     }
     // return an input:
     return input;
    }

    // called when SPECIAL child is created:
    private function onTempUICCreated(event:FlexEvent):void {
     // keep the ref to the SPECIAL child:
     var renderer:UIComponent = UIComponent(event.target);
     // output - this will contain max size for each column:
     var maxLengths:Object = {};
     // temp variables:
     var key:String = "";
     var i:int=0;
     // for each item in the DP:
     for ( i=0; i<dp.length; i++ ) {
      var o:Object = dp.getItemAt(i);
      // for each key in the DP row:
      for ( key in o ) {
       // if the output doesn't have current key yet create it and set to 0:
       if ( !maxLengths.hasOwnProperty(key) ) {
        maxLengths[key] = 0;
       }
       // check if it's simple object (may cause unexpected issues for Boolean):
       if ( ObjectUtil.isSimple(o[key]) ) {
        // measure the text:
        var cellMetrics:TextLineMetrics = renderer.measureText(o[key]+"");
        // and if the width is greater than longest found up to now:
        if ( cellMetrics.width > maxLengths[key] ) {
         // set it as the longest one:
         maxLengths[key] = cellMetrics.width;
        }
       }
      }
     }

     // apply column sizes:
     for ( key in maxLengths ) {
      for ( i=0; i<dg.columnCount; i++ ) {
       // if the column actually exists:
       if ( DataGridColumn(dg.columns[i]).dataField == key ) {
        // set size + some constant margin
        DataGridColumn(dg.columns[i]).width = Number(maxLengths[key]) + 12;
       }
      }
     }
     // cleanup:
     removeChild(getChildByName("$someTempUICToRemoveAfterFinished"));
    }

   ]]&gt;
  </mx:Script>

  <mx:DataGrid id="dg" horizontalScrollPolicy="on" dataProvider="{calcMaxLengths(dp)}" width="400">
   <mx:columns>
    <mx:DataGridColumn dataField="col1" width="40" />
    <mx:DataGridColumn dataField="col2" width="100" />
   </mx:columns>
  </mx:DataGrid>

 </mx:WindowedApplication>
[/sourcecode]</pre>
<p>Sample:</p>
<p>[SWF]/wp-content/uploads/2009/06/TextTest.swf, 450, 240[/SWF]</p>
<p>This code works just fine however it may be not efficient enough when applied to large data providers.</p>
<p>Source code is also available on <a href="http://stackoverflow.com/questions/1002518/dynamically-change-the-width-of-datagrid-column-in-flex/1004305#1004305">stackoverflow.com</a> under the original entry.</p>
]]></content:encoded>
			<wfw:commentRss>http://gruchalski.com/2009/06/16/flex-datagridcolumn-width-set-to-the-longest-value-in-that-column/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
