【问题标题】:Dynamically change the width of Datagrid column in FLEX在 FLEX 中动态改变 Datagrid 列的宽度
【发布时间】:2010-11-03 09:40:50
【问题描述】:

我们可以通过单击列的边框来动态更改数据网格列的宽度,以便显示太长而无法显示且需要滚动的完整字符串?如果有,怎么做?

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

【问题讨论】:

    标签: apache-flex dynamic datagridview column-width


    【解决方案1】:

    对于 Gridview 控件,您可以向下钻取 SelectedRowStyle 属性并将 Wrap 设置为 True。

    【讨论】:

    • 哦...我想您是在谈论 ASP.NET ...我的问题是关于 Flex。抱歉,我一开始没有提到。
    【解决方案2】:

    这是我想出的,但是对于大型数据提供商来说可能效率不高:

    <?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>
    

    【讨论】:

    • 有点疯狂,但很棒!一种更简单、更有效的方法是遍历列值,找到最大字符长度,然后乘以一个固定常数。
    【解决方案3】:

    所以我遇到了类似的问题,这就是我发现的。如果你设置:

    horizontalScrollPolicy="off"
    

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

    【讨论】:

      【解决方案4】:

      我最近遇到了同样的问题,我发现的唯一解决方案是使用自定义函数来优化 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>ccoenraets@fictitious.com</email>
                  <active>true</active>
              </employee>
              <employee>
                  <name>Joanne Wall</name>
                  <phone>555-219-2012</phone>
                  <email>jwall@fictitious.com</email>
                  <active>true</active>
              </employee>
              <employee>
                  <name>Maurice Smith</name>
                  <phone>555-219-2012</phone>
                  <email>maurice@fictitious.com</email>
                  <active>false</active>
              </employee>
              <employee>
                  <name>Mary Jones</name>
                  <phone>555-219-2000</phone>
                  <email>mjones@fictitious.com</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>
      

      【讨论】:

      • -1 ...链接到独家专家交流不是很有帮助。
      猜你喜欢
      • 2010-11-20
      • 2012-11-20
      • 1970-01-01
      • 2011-04-05
      • 1970-01-01
      • 1970-01-01
      • 2011-10-14
      • 2011-01-11
      • 2015-09-22
      相关资源
      最近更新 更多