Как найти высоту динамического компонента Flex, используемого в качестве всплывающего окна - PullRequest
1 голос
/ 08 июля 2011

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

Однако при отображении всплывающей подсказки иногда она выходит за границы приложения флэш-памяти, поэтому я быхотелось бы иметь возможность обнаруживать это вхождение и перемещать подсказку.

Проблема в том, что высота и ширина компонента, по-видимому, недоступны до тех пор, пока они не будут визуализированы менеджером всплывающих окон.(т. е. они всегда равны 0)

Но я не знаю какого-либо способа узнать, когда всплывающее окно действительно отображается, и, следовательно, доступны значения высоты / ширины.

Я попытался добавитьпрослушиватель события resize компонента, но он, похоже, не работает, хотя я наверняка мог бы сделать что-то не так, поскольку мне кажется, что событие resize дает вам только «oldWidth» и «oldHeight» объекта,который, на первый взгляд, будет 0 ... и бесполезен для меня.

Любые идеи о том, как действовать?

----- Редактировать ----- У меня естьбазовый класс, подобный этому:

public class TTComponent extends Canvas
{
  var _parentC:UIComponent;
  var popped:Boolean = false;
  var timer:Timer;
  var _comp:UIComponent;

  public function set parentComponent(pC:UIComponent):void 
  {
    _parentC = pc;
    _parentC.addEventListener(MouseEvent.MOUSE_OUT, mouseOut);
    _parentC.addEventListener(MouseEvent.MOUSE_OVER, mouseOver);
  }
  public function mouseOver(evt:MouseEvent):void
  {
    if (_parentC != null)
    {
      timer = new Timer(150,1);
      _comp = this;
      timer.addEventListener(TimerEvent.TIMER_COMPLETE, function( tevt:TimerEvent ):void 
      {
        this.move( somex, somey);
        if (popped != true)
        {
           PopUpManager.addPopUp(_comp, parentComponent );
           popped = true;
        });
        timer.start();
    }
  }

  public function mouseOut(evt:MouseEvent ):void
  {
    if ( timer )
    {
      timer.stop();
      timer = null;
    }
    //If we popped up, remove the popup
    if ( popped )
    {
      PopUpManager.removePopUp( _comp );
      popped = false;
      parentC .removeEventListener(MouseEvent.MOUSE_OUT, mouseOut);
      parentC .removeEventListener(MouseEvent.MOUSE_OVER, mouseOver);
    }
  }
}

Затем расширенный рендер:

<c:TTComponent name="T" xmlns:fx="http://ns.adobe.com/mxml/2009" 
                          xmlns:s="library://ns.adobe.com/flex/spark" 
                          xmlns:mx="library://ns.adobe.com/flex/mx" 
                          xmlns:c="components.*">
  <s:BorderContainer>
    ...about 30 labels grouped in various manners
    ...2 lists with inline item renderers
  </s:BorderContainer>
</c:TTComponent>

Теперь код называется так:

var w = new TTComponent();
w.data = data;
win.parentComponent = this;

Thisдобавит слушателей к событиям mouse over и mouse out на родительском объекте, какими бы они ни были, а затем соответственно отобразит или скроет подсказку.

------ Редактировать ------

Используя часть предложенного ниже комментарием, я пришел к такому решению:

Inside класс TTComponent:

import flash.events.Event;
import mx.binding.utils.ChangeWatcher;

private var heightWatcher:ChangeWatcher;


public function set parentComponent 
{
  ...
  heightWatcher = ChangeWatcher.watch(this,'height',onSizeChange);
}

public function onSizeChange(evt:Event):void
{
  if (this.height != 0)
  {
    ....calculate the new component coords
    this.move(newx, newy);
  }
}

Обратите внимание, что этот дополнительный код не привязывается ни к какой переменной компонента, он просто добавляет наблюдатель для свойства компонента.

Ответы [ 4 ]

0 голосов
/ 10 июля 2011

Это может быть грязно, но во всплывающем компоненте вы можете добавить прослушиватель событий после запуска завершения, если высота или ширина == 0, то вы устанавливаете функцию TimeTimeout () после, скажем, 100 мс, пока не получите действительные данные .

Да, я знаю, что это что-то вроде хака, но в конечном итоге они сообщат правильно измеренные значения, поэтому он не будет вызывать это много раз.

Просто идея, если вы не в срок или что-то подобное, не критично. :)

0 голосов
/ 08 июля 2011

Попробуйте прослушать обновление завершено Событие этого компонента. Пусть это поможет вам. :)

0 голосов
/ 08 июля 2011

Вы также можете попробовать связать свою ширину и рост. Если они сделаны привязываемыми в вашем классе, flex автоматически отрегулирует ширину и высоту вашего всплывающего окна.

При использовании mxml для привязки вы можете просто сделать что-то вроде этого

<mx:YourComponent height="{HeightOfYourTooltip}" width="{WidthOfYourTooltip}"></mx:YourComponent>

Вы также можете добавить eventListener, который прослушивает событие изменения, если вы хотите изменить положение вашего компонента, например

<mx:YourComponent height="{HeightOfYourTooltip}" width="{WidthOfYourTooltip}" change="yourComponentResizeHandler()"></mx:YourComponent>

Если вы используете запрограммированный подход, вам следует использовать сменщик часов. Ниже показано, как вы можете это использовать.

ChangeWatcher.watch(YourComponent, "width", repositionHandler);
ChangeWatcher.watch(YourComponent, "height", repositionHandler);

Если вы хотите отслеживать изменения других переменных или свойств, обязательно добавьте тег [Bindable] над переменными в вашем классе, например,

[Bindable]
var myVariable:SomeVariable;

Надеюсь, это поможет.

0 голосов
/ 08 июля 2011

Для отображения подсказки, какие элементы управления вы используете в itemRenderer?Текст или метка?

...