2009-03-04 3 views
4

Я пытаюсь создать datagrid, который будет изменяться по вертикали, чтобы все визуализаторы отображались в полном объеме. Кроме того,Flex - проблема с автоматическим изменением размера datagrid

  • Renderers имеют переменную высоту
  • Renderers может изменить размер себя

Вообще говоря, поток событий выглядит следующим образом:

  • Один из элементов рендереров изменяет себя (обычно в ответ на щелчок пользователя и т. д.)
  • Он отправляет пузырящее событие, которое родительский набор данных поднимает
  • DataGrid пытается изменить размер, чтобы все визуализаторы оставались видимыми в полном объеме.

В настоящее время я использую этот код в сетке данных для вычисления высоты:

height = measureHeightOfItems(0, dataProvider.length) + headerHeight; 

Это, как представляется, получить неправильную высоту. Я пробовал несколько вариантов, включая callLater (чтобы гарантировать, что размер изменен, так что показатель может работать корректно) и переопределяя meausre() и вызывая invalidateSize()/validateSize(), но не работает.

Ниже приведены 3 класса, которые иллюстрируют проблему. Щелчок по кнопке в средствах рендеринга элементов изменяет размер рендеринга. Сетка также должна расширяться, чтобы все три рендеринга были показаны полностью.

Любые предложения были бы весьма полезными.

С уважением

Marty

DataGridProblem.mxml (файл приложения)

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" 
    xmlns:view="view.*"> 
    <mx:ArrayCollection id="dataProvider"> 
     <mx:String>Item A</mx:String> 
     <mx:String>Item B</mx:String> 
     <mx:String>Item C</mx:String> 
    </mx:ArrayCollection> 
    <view:TestDataGrid 
     id="dg" 
     dataProvider="{ dataProvider }" 
     width="400"> 
     <view:columns> 
      <mx:DataGridColumn dataField="text" /> 
      <mx:DataGridColumn itemRenderer="view.RendererButton" /> 
     </view:columns> 
    </view:TestDataGrid> 
</mx:Application> 

view.TestDataGrid.as

package view 
{ 
    import flash.events.Event; 

    import mx.controls.DataGrid; 
    import mx.core.ScrollPolicy; 

    public class TestDataGrid extends DataGrid 
    { 
     public function TestDataGrid() 
     { 
      this.verticalScrollPolicy = ScrollPolicy.OFF; 
      this.variableRowHeight = true; 
      this.addEventListener(RendererButton.RENDERER_RESIZE , onRendererResize); 
     } 
     private function onRendererResize(event : Event) : void 
     { 
      resizeDatagrid(); 
     } 
     private function resizeDatagrid():void 
     { 
      height = measureHeightOfItems(0, dataProvider.length) + headerHeight; 
     } 
    } 
} 

view.RendererButton.mxml

<?xml version="1.0" encoding="utf-8"?> 
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml"> 
    <mx:Button width="50" height="50" 
     click="onClick()" /> 

    <mx:Script> 
     <![CDATA[ 

      public static const RENDERER_RESIZE : String = "resizeRenderer"; 
      private function onClick() : void 
      { 
       this.height += 20; 
       dispatchEvent(new Event(RENDERER_RESIZE , true)); 
      } 
     ]]> 
    </mx:Script> 
</mx:HBox> 

ответ

0

Для чего это стоит, мне так и не удалось решить эту проблему. Код быстро стал одержим борьбой с краевыми случаями.

Я закончил тем, что выбрал подход dataGrid и написал решение, используя VBox & HBox для упрощения изменения размера.

+2

d oh ... там должен быть способ работать. – DyreSchlock

0

Чтобы сделать такие вещи, как переменной ширины и высоты ячеек/строк/столбцов, а также других «продвинутых» функций - попробуйте расширить AdvancedDataGrid, а не старше, более скучный DataGrid

+0

Hi В этом вопросе использование AdvancedDataGrid не является вариантом. С уважением Marty –

+0

Под «скучным», я полагаю, вы имеете в виду «менее багги». – ggkmath

0

для чего его стоит; вы должны были использовать свойство variableRowHeight = "true" в datagrid/advanced datagrid.

Если вам становится лучше, я создал пользовательское решение VBox, HBox, после чего обнаружил, что его уже сделано !! (snap!)

удачи!

+0

Hi Vusi Я уже пробовал использовать variableRowWidth = true, но это не решило проблему (как кажется, вы теперь сталкиваетесь) –

0

Существует основная проблема для вашего подхода. ItemRenderers предназначены для последовательного отображения элемента данных, и если вы выбрасываете текущий рендерер и создаете новый и устанавливаете свойство данных нового средства визуализации, он должен выглядеть идентичным предыдущему. Вы не должны вносить временные изменения в средство визуализации вне элемента данных, и рендеринг будет вести себя странно, когда вы это сделаете.

Я подозреваю, что если вы изменили объекты модели данных, чтобы содержать свойство count, и данные привязали высоту вашего визуализатора к выражению «{50 + data.count * 20}», а затем сделали данные о приращении обработчика щелчка кнопки. счет на 1, что это будет работать правильно. (Мой опыт в том, что DataGrid будет перерисовываться с соответствующим размером для каждой строки, если изменения будут выполнены в результате свойства данных, прежде чем он вызовет makeRowsAndColumns().) Я не пробовал этот подход для вашего примера , поэтому я не могу точно сказать, что это действительно работает, но, конечно, это правильное мышление для работы с рендерингом элементов.

2

Вы можете достичь этой цели с помощью AdvancedDataGrid, используя следующий код. Если вы удалите this.headerHeight, он также работает для List, что заставляет меня думать, что он должен работать для обычного старого DataGrid.

override protected function measure():void 
    { 
    super.measure(); 

    if (this.dataProvider) 
    { 
    var newHeight : int = measureHeightOfItems(0, this.dataProvider.length) + this.headerHeight; 

    this.minHeight = newHeight; 
    this.height = newHeight; 
    } 
    } 
+0

Отличный материал! Вот более красивая версия: 'var newHeight: int = measureHeightOfItems (-1, dataProvider.length);' –

1

Чтобы изменить размер сетки данных во время выполнения ... используйте свойство rowcount и привяжите его к длине данных. По мере обновления датапараудера будет приведена строка.
Вы можете увидеть пример того, как использовать сверку в гибком here

+0

не будет работать, если переменнаяRowHeight = "true" для источников данных искры. – ggkmath

0

У меня есть немного немного грязное решение такой проблемы Попробуйте один

private function ResizeGrid():void{ 
    if (this.dg.maxVerticalScrollPosition > 0){ 
     this.dg.height +=5; 
     setTimeout(this.ResizeGrid,100); 
    } 
} 

И вызывает вашу функцию с некоторой задержкой, как следует

setTimeout(this.ResizeGrid,100); 

Это грязный подход, но это работает для меня :)

0

следующий код в gridItemRenderer помог мне:

protected function resize():void 
{ 
    column.grid.validateSize(); 
    column.grid.validateDisplayList(); 
} 
0

У меня есть решение этой проблемы, изменения визуализации необходимо синхронизировать с DataProvider. Тогда метод measureHeightOfItems будет давать точные результаты.

Смежные вопросы