My renderer is a modified copy of ListItemRenderer that adds some
components, toggling their visibility based on the item data.  Almost
everything is working, except:

One of the components is a RadioButtonGroup.  In the commitProperties
method, I look a the item data(XML) and get the value of a selectedValue
attribute. If the atribute is null or empty, I set the RBG.selectedValue
= null; This works fine, until I scroll.

When I scroll, the recycled renderer gets the correct item, with a
null/empty attribute, sets the selectedValue to null, but the
selectedValue assignment does not "take".  I test the value in the next
line and it has the value from the previous item.  

Here are the snippets:

override protected function commitProperties():void
{
  trace("commitProperties()")
  super.commitProperties();
...
  sTempValue = _data.attribute("selectedValue");
  trace("...SETTING Item #" + [EMAIL PROTECTED]);
  trace(".....attribute value=" + sTempValue)
  if (sTempValue.length > 0)  {
     trace("++++++ non-empty attribute value, setting selectedValue=" +
sTempValue)
     rgbValue.selectedValue = sTempValue;
   }
   else  {
     trace("------ null attribute value, setting selectedValue=NULL" )
    rgbValue.selectedValue = null;
   }
   //now check the selecteedvalue
   if (rgbValue.selectedValue != null)  {
     trace("......Check the selectedValue, item" + [EMAIL PROTECTED] +
".selectedValue=" + rgbValue.selectedValue);
     trace("")
   }

And the trace for a true value item:
...SETTING Item #1
.....attribute value=P
++++++ non-empty attribute value, setting selectedValue=P
......Check the selectedValue, item1.selectedValue=P

And the trace for a scrolled item:
...SETTING Item #28
.....attribute value=
<===ATTRUBUTE IS EMPTY
------ null attribute value, setting selectedValue=NULL
<===SETTING TO NULL
......Check the selectedValue, item28.selectedValue=P           <===WTF?


I'll attach the full IR as well.
Thanks, 
Tracy
 <<LIR.txt>> 
////////////////////////////////////////////////////////////////////////////////
//
//  Copyright (C) 2003-2006 Adobe Macromedia Software LLC and its licensors.
//  All Rights Reserved. The following is Source Code and is subject to all
//  restrictions on such code as contained in the End User License Agreement
//  accompanying this product.
//
////////////////////////////////////////////////////////////////////////////////

package 
{

import flash.display.DisplayObject;
import flash.geom.Point;
import flash.geom.Rectangle;
import mx.core.IDataRenderer;
import mx.core.IFlexDisplayObject;
import mx.core.IToolTip;
import mx.core.UIComponent;
import mx.core.UITextField;
import mx.core.mx_internal;
import mx.events.FlexEvent;
import flash.events.Event;
import mx.events.ToolTipEvent;
import mx.controls.listClasses.*;
import mx.controls.RadioButtonGroup;
import mx.controls.RadioButton;
import mx.controls.RadioButtonGroup;
import mx.controls.Alert;
import mx.controls.Label;
import mx.containers.Canvas;
import mx.styles.StyleManager;
import mx.styles.CSSStyleDeclaration;

use namespace mx_internal;

//--------------------------------------
//  Events
//--------------------------------------

/**
 *  Dispatched when the <code>data</code> property changes.
 *
 *  <p>When you use a component as an item renderer,
 *  the <code>data</code> property contains the data to display.
 *  You can listen for this event and update the component
 *  when the <code>data</code> property changes.</p>
 * 
 *  @eventType mx.events.FlexEvent.DATA_CHANGE
 */
[Event(name="dataChange", type="mx.events.FlexEvent")]

//--------------------------------------
//  Styles
//--------------------------------------

/**
 *  Text color of a component description.
 *  @default 0x0B333C
 */
[Style(name="color", type="uint", format="Color", inherit="yes")]

/**
 *  Text color of the component if it is disabled.
 *  
 *  @default 0xAAB3B3
 */
[Style(name="disabledColor", type="uint", format="Color", inherit="yes")]

/**
  *  Defines an item renderer that displays the two line states for the
  * InsideWood SearchCriteria list
 */
public class LIRSearchCriteria extends UIComponent
                implements IDataRenderer,
                IDropInListItemRenderer, IListItemRenderer
{

  /**  Constructor.   */
  public function LIRSearchCriteria()
  {
    super();  
    mouseEnabled = false; 
    addEventListener(ToolTipEvent.TOOL_TIP_SHOW, toolTipShowHandler);
    styleDeclHeader = StyleManager.getStyleDeclaration(".searchCriteriaHeader");
    styleDeclItem = StyleManager.getStyleDeclaration(".searchCriteriaItem");
    backgroundColorHeader = styleDeclHeader.getStyle("backgroundColor");
    backgroundColorItem = styleDeclItem.getStyle("backgroundColor");

    //backgroundColorItem = 
  }

  private const RBG_VALUE_WIDTH:int = 70;
  private const ITEM_NUM_WIDTH:int = 30
  
  private var listOwner:ListBase;
  private var _data:Object;
  protected var itemNum:UITextField;      //The internal UITextField that 
displays the Item number in this renderer.
  protected var description:UITextField;    //The internal UITextField that 
displays the description in this renderer.
  protected var uicRGBValue:UIComponent;      //The internal UIComponent that 
displays the RadioButton Group in this renderer.
  protected var rbgValueLabels:Canvas;      //The internal UIComponent that 
displays the labels for the RadioButton Group in this renderer.
  protected var rgbValue:RadioButtonGroup; //the actual readio button group
  protected var uitTest:UITextField;
  
  protected var styleDeclHeader:CSSStyleDeclaration;
  protected var styleDeclItem:CSSStyleDeclaration;
  protected var backgroundColorHeader:Number;
  protected var backgroundColorItem:Number;
  protected var backgroundFillColor:Number;
  private var _listData:ListData;        //Storage for the listData property.  

  override public function get baselinePosition():Number
  {
    return description.baselinePosition;
  }


  [Bindable("dataChange")]
  public function get data():Object
  {
    return _data;
  }

  public function set data(value:Object):void
  {
    //trace(".set data()")
    _data = value;
    invalidateProperties();
    dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE));
  }//set data


  [Bindable("dataChange")]  
  public function get listData():BaseListData
  {
    return _listData;
  }

  public function set listData(value:BaseListData):void
  {
    _listData = ListData(value);
    invalidateProperties();
  }


  override protected function createChildren():void
  {
    //trace("createChildren()")
    super.createChildren();
    
    if (!itemNum)  {                             //create itemNum
      itemNum = new UITextField();
      itemNum.styleName = this;
      itemNum.multiline = false;
      itemNum.wordWrap = false;
      itemNum.visible = false;
      itemNum.x = 0;
      itemNum.y = 0;  
      itemNum.width = 30;  
      itemNum.height = 18;  //??  
      addChild(itemNum);
    }  
    if (!description)                              //create description
    {
      description = new UITextField();
      description.styleName = this;
      description.y = 0;
      addChild(description);
    }
    if (!uicRGBValue)  {                           //create radio button group
      addRBG();    //add the radio buttons
    }  
    if (!rbgValueLabels)  {                        //create radio button labels
      addRBGLabels();    
    }        
  }//createChildren

  /**
   *  @private
   *  Apply the data and listData.
   *  display the itemNum and RBG if this is an item line
   *  and set the text into the text field.
   */
  override protected function commitProperties():void
  {
    trace("commitProperties()")
    super.commitProperties();
    var sTempValue:String = "";
    if (_data != null)  {                              //if we have data
      listOwner = ListBase(_listData.owner);
      
      var sItemNum:String = _data.attribute("item");
      if (sItemNum.length > 0)  {                      //this is an item line
        this.styleName = "searchCriteriaItem";
        backgroundFillColor = backgroundColorItem;      
        itemNum.visible = true;                        //show the itemNum
        itemNum.text = [EMAIL PROTECTED] + ".";              //set itemNum value
        uicRGBValue.visible = true;                    //show the radio buttons
        //rgbValue.selectedValue = [EMAIL PROTECTED]; //no attribute returns 
null
        sTempValue = _data.attribute("selectedValue");
        trace("...SETTING Item #" + [EMAIL PROTECTED]);
        trace(".....attribute value=" + sTempValue)
        if (sTempValue.length > 0)  {
          trace("++++++ non-empty attribute value, setting selectedValue=" + 
sTempValue)
          rgbValue.selectedValue = sTempValue;
        }
        else  {
          trace("------ null attribute value, setting selectedValue=NULL" )
          rgbValue.selectedValue = null;
        }
        //now check the selecteedvalue
        if (rgbValue.selectedValue != null)  {
          trace("......Check the selectedValue, item" + [EMAIL PROTECTED] + 
".selectedValue=" + rgbValue.selectedValue);
          trace("")
        }
        rbgValueLabels.visible = false;                //do not show the labels 
} 
      }
      else  {
        this.styleName = "searchCriteriaHeader";
        backgroundFillColor = backgroundColorHeader;
        rbgValueLabels.visible = true;
        itemNum.visible = false;                       //do not show the itemNum
        uicRGBValue.visible = false;
      }
                
      description.text = [EMAIL PROTECTED];                 //the description 
is always visible
      description.multiline = true;    
      description.wordWrap = true; 
      
       
      if (listOwner.showDataTips)  {
        if (description.textWidth > description.width ||
          listOwner.dataTipFunction != null)  {
          toolTip = listOwner.itemToDataTip(_data);
        }
        else  {
          toolTip = null;
        }
      }
      else  {
        toolTip = null;
      }//if (listOwner.showDataTips)
    }
    else  {
      description.text = " ";
      toolTip = null;
    }//if (_data != null)
  }


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

    var w:Number = 0;
    if (isNaN(explicitWidth))
    {
      w += description.getExplicitOrMeasuredWidth();
      measuredWidth = w;
      measuredHeight = description.getExplicitOrMeasuredHeight();
    }
    else
    {
      measuredWidth = explicitWidth;
      description.setActualSize(Math.max(explicitWidth - w, 4), 
description.height);
      measuredHeight = description.getExplicitOrMeasuredHeight();
    }
  }


  override protected function updateDisplayList(unscaledWidth:Number,
                          unscaledHeight:Number):void
  {
    //trace("....updateDisplayList()")
    super.updateDisplayList(unscaledWidth, unscaledHeight);

    var startX:Number = 0;

    if (itemNum.visible == true)  {
      startX = ITEM_NUM_WIDTH + 5;
    }    

    description.x = startX;
    description.setActualSize(unscaledWidth - startX - RBG_VALUE_WIDTH, 
measuredHeight);

    rbgValueLabels.x = unscaledWidth - RBG_VALUE_WIDTH;
    uicRGBValue.x = unscaledWidth - RBG_VALUE_WIDTH;

    var labelColor:Number;
    if (data && parent)
    {
      if (!enabled)
        labelColor = getStyle("disabledColor");
      else if (listOwner.isItemHighlighted(listData.uid))
        labelColor = getStyle("textRollOverColor");
      else if (listOwner.isItemSelected(listData.uid))
        labelColor = getStyle("textSelectedColor");
      else
        labelColor = getStyle("color");

       description.setColor(labelColor);
    }
    
    //Draw the divider line
    graphics.clear();
    var iLineY:int = measuredHeight - 3;
    graphics.lineStyle(.7, 0x999999,.3,false,"NONE");
    graphics.moveTo(0,iLineY);
    graphics.lineTo(unscaledWidth,iLineY);
    
    //color the background
    graphics.beginFill(backgroundFillColor,1.0);
    graphics.drawRect(0, 0, measuredWidth, measuredHeight);
    graphics.endFill();
  }
  
  /**   Misc functions    */
  
  private function addRBGLabels():void
  {
    var lblNew:Label;
    rbgValueLabels = new Canvas;
    rbgValueLabels.width = RBG_VALUE_WIDTH;
    rbgValueLabels.height = 16;    
    rbgValueLabels.visible = false;  
    lblNew = new Label();
    lblNew.text = "P";
    rbgValueLabels.addChild(lblNew);
    lblNew = new Label();
    lblNew.x = 18;
    lblNew.text = "A";
    rbgValueLabels.addChild(lblNew);    
    lblNew = new Label();
    lblNew.x = 35;
    lblNew.text = "R";
    rbgValueLabels.addChild(lblNew);
    lblNew = new Label();
    lblNew.x = 53;
    lblNew.text = "E";
    rbgValueLabels.addChild(lblNew);  

    addChild(rbgValueLabels);    
  }//addRBGLabels  

  
  private function addRBG():void
  {
    //trace("addRBG")
    rgbValue = new RadioButtonGroup();  //create the group
    rgbValue.addEventListener(Event.CHANGE,onValueChange)
    var oTemp:*;
    uicRGBValue = new UIComponent;                      //create the container

    uicRGBValue.y = 2;
    uicRGBValue.width = RBG_VALUE_WIDTH;
    uicRGBValue.height = 16;
    uicRGBValue.visible = true;
    //Now add the buttons
    oTemp = new RadioButton();
    oTemp.id = "P";
    oTemp.value = "P";
    oTemp.group = rgbValue;
    uicRGBValue.addChild(oTemp);
    oTemp = new RadioButton();
    oTemp.x = 17;
    oTemp.id = "A";
    oTemp.value = "A";
    oTemp.group = rgbValue;
    uicRGBValue.addChild(oTemp);    
    oTemp = new RadioButton();
    oTemp.x = 34;
    oTemp.id = "R";
    oTemp.value = "R";
    oTemp.group = rgbValue;
    uicRGBValue.addChild(oTemp);
    oTemp = new RadioButton();
    oTemp.x = 51;
    oTemp.id = "E";
    oTemp.value = "E";
    oTemp.group = rgbValue;
    uicRGBValue.addChild(oTemp);        
    addChild(uicRGBValue)    
  }//addRBG

  //--------------------------------------------------------------------------
  //
  //  Event handlers
  //
  //--------------------------------------------------------------------------

  /**
   *  Positions the tooltip.
   *
   *  @param The Event object.
   */
  protected function toolTipShowHandler(event:ToolTipEvent):void
  {
    var toolTip:IToolTip = event.toolTip;

    // Calculate global position of description.
    var pt:Point = new Point(0, 0);
    pt = description.localToGlobal(pt);
    pt = stage.globalToLocal(pt);

    toolTip.move(pt.x, pt.y + (height - toolTip.height) / 2);

    var screen:Rectangle = systemManager.screen;
    var screenRight:Number = screen.x + screen.width;
    if (toolTip.x + toolTip.width > screenRight)
      toolTip.move(screenRight - toolTip.width, toolTip.y);

  }
  
  /** runs when user clicks radiobutton group */
  private function onValueChange(oEvent:Event):void
  {
    var sSelectedValue:String = oEvent.currentTarget.selectedValue; //get the 
selectedValue
    [EMAIL PROTECTED] = sSelectedValue;               //save the value in the 
xml    
  }//onValueChange  

  /**
   *  @private
   */
  mx_internal function getLabel():UITextField
  {
    return description;
  }
  
  
}

}

Reply via email to