2009-06-16 72 views
3

我们是否可以通过单击列的边框来动态更改数据列的宽度,以显示太长而无法显示并需要滚动的完整字符串?如果是这样,怎么样?动态更改FLEX中的Datagrid列的宽度

另外,如何确保列宽根据字符数/字符串长度动态变化;因为很多次数据太长而无法显示。在显示到数据网格之前,我们可以设置列宽以考虑数据的长度吗?

回答

0

对于Gridview控件,可以深入到SelectedRowStyle属性并将Wrap设置为True。

+0

哦......我想你是相对于谈话ASP.NET ...我的问题是关于Flex。对不起,我最初没有提到它。 – user120118 2009-06-16 19:05:44

+0

我已经进行了纠正。 – user120118 2009-06-16 19:06:20

1

这是我想出了但它可能不适合大数据提供高效:

<?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")); 
      } 

     ]]> 
    </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> 
+0

有点疯狂,但伟大的工作!更容易和更有效的方法是迭代列值,查找最大字符长度,并将其乘以固定的常量。 – JTtheGeek 2010-09-23 19:03:25

2

所以我有一个类似的问题,这里是我发现了什么。如果设置为:

horizontalScrollPolicy="off" 

然后,列宽将自动调整大小以适应DataGrid的宽度。只要将滚动设置为打开或关闭并且未设置为自动,您也可以手动设置列宽。我发现了一篇有趣的文章,http://junleashed.wordpress.com/2008/07/10/flex-datagridcolumn-width-management/。基本上,他手动管理列宽,然后计算滚动条是否应该打开或关闭。

1

我最近遇到了同样的问题,我发现的唯一的解决办法是使用自定义的函数优化DataGrid的列宽的建议here

<?xml version="1.0" encoding="utf-8"?> 
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> 
<mx:Script> 
<![CDATA[ 
import mx.core.UITextField; 
import mx.controls.dataGridClasses.DataGridItemRenderer; 

public function optimiseGridColumns(dg:DataGrid):void { 
         var dgCol:DataGridColumn; 
         var renderer:UITextField; 
         var tf:TextFormat; 
         var col:int; 

         if (dg.columnCount > 0 && dg.dataProvider != null) { 
         // initialize widths array 
           var widths:Array = new Array (dg.columnCount); 
           for (col = 0; col < widths.length; ++col) { 
             widths[col] = -1; 
           } 

         // go through each data item in the grid, estimate 
         // the width of the text in pixels 
           for each (var item:Object in dg.dataProvider) { 
             for (col = 0; col < widths.length; ++col) { 
               renderer = new DataGridItemRenderer(); 
               // Must add to datagrid as child so that it inherits 
               // properties essential for text width estimation, 
               // such as font size 
               dg.addChild(renderer); 

               dgCol = dg.columns[col] as DataGridColumn; 
               renderer.text = dgCol.itemToLabel(item); 
               widths[col] = Math.max(renderer.measuredWidth + 10,widths[col]); 

               // remove renderer from datagrid when we're done 
               dg.removeChild(renderer); 
             } 
           } 

           // go through headers in the grid, estimate the width of 
           // the text in pixels, assuming the text is bold 
           for (col = 0; col < widths.length; ++col) { 
             // it's ok to reuse renderer, but I chose not 
             // to for safety reasons. Optimize if needed. 
             renderer = new DataGridItemRenderer(); 

             // Must add to datagrid as child so that it inherits 
             // properties essential for text width estimation, 
             // such as font size 
             dg.addChild(renderer); 

             dgCol = dg.columns[col] as DataGridColumn; 
             renderer.text = dgCol.headerText; 

             tf = renderer.getTextFormat(); 
             tf.bold = true; 
             renderer.setTextFormat (tf); 

             widths[col] = Math.max(renderer.measuredWidth + 25, widths[col]); 

             // remove renderer from datagrid when we're done 
             dg.removeChild(renderer); 
           } 

           // set width of columns to determined values 
           for (col = 0; col < widths.length; ++col) 
           { 
             if (widths[col] != -1) 
             { 
               dg.columns[col].width = widths[col]; 
             } 
           } 
         } 
       } 

]]> 
</mx:Script> 
    <mx:XMLList id="employees"> 
     <employee> 
      <name>Christina Coenraets</name> 
      <phone>555-219-2270</phone> 
      <email>[email protected]</email> 
      <active>true</active> 
     </employee> 
     <employee> 
      <name>Joanne Wall</name> 
      <phone>555-219-2012</phone> 
      <email>[email protected]</email> 
      <active>true</active> 
     </employee> 
     <employee> 
      <name>Maurice Smith</name> 
      <phone>555-219-2012</phone> 
      <email>[email protected]</email> 
      <active>false</active> 
     </employee> 
     <employee> 
      <name>Mary Jones</name> 
      <phone>555-219-2000</phone> 
      <email>[email protected]</email> 
      <active>true</active> 
     </employee> 
    </mx:XMLList> 
     <mx:DataGrid id="dg1" width="100%" height="100%" rowCount="5" dataProvider="{employees}" creationComplete="optimiseGridColumns(dg1)"> 
      <mx:columns> 
       <mx:DataGridColumn dataField="name" headerText="Name"/> 
       <mx:DataGridColumn dataField="phone" headerText="Phone"/> 
       <mx:DataGridColumn dataField="email" headerText="Email"/> 
      </mx:columns> 
     </mx:DataGrid> 

</mx:Application>