Flex SkinnableContainer skin access Group inside contentGroup - actionscript-3

I have skin class in which I defined a Group inside my contentGroup:
<s:Group id="contentGroup" left="0" right="0" top="0" bottom="0" minWidth="475" minHeight="0">
<s:layout>
<s:HorizontalLayout paddingLeft="0" paddingRight="0" paddingTop="0" paddingBottom="0" gap="2" />
</s:layout>
<s:Group id="group_nav_custom_comp_hgroup_prevnext" left="0" right="0" top="0" bottom="0" minWidth="100" minHeight="0">
<s:layout>
<s:HorizontalLayout paddingLeft="0" paddingRight="0" paddingTop="0" paddingBottom="0" gap="5" />
</s:layout>
<s:Button label="Test Button"/>
</s:Group>
</s:Group>
Now, in my CustomComponent that extends the skin class above I am trying to access the "group_nav_custom_comp_hgroup_prevnext" (which is the child group inside the contentGroup) so I can add elements to it at runtime:
public class GroupNavCustomContainer extends SkinnableContainer
{
private var m_group_prev_next:Group = null;
private var m_bAdded_btns:Boolean = true;
private var _prevbtn:UIComponent = null;
public function GroupNavCustomContainer()
{
super();
setStyle("skinClass", GroupNavCustomSkin);
}
//----------------------------------
public function set prevBtn(ui_comp_prev:UIComponent):void
{
if(m_group_prev_next)
{
_prevbtn = ui_comp_prev;
m_bAdded_btns = true;
invalidateProperties();
}
}
//-------------------------------------------------------------------------
override protected function partAdded(partName:String, instance:Object):void
{
trace("In partAdded");
if(partName == "contentGroup")
{
var group:Group = instance as Group;
var visualElem:IVisualElement = group.getElementAt(0);
m_group_prev_next = visualElem as Group;
}
super.partAdded(partName, instance);
}
//------------------------------------------------------------------------
override protected function commitProperties():void
{
super.commitProperties();
if (m_bAdded_btns)
{
m_bAdded_btns = false;
m_group_prev_next.addElement(_prevbtn);
}
}
}
The result is my: group_nav_custom_comp_hgroup_prevnext is just not showing up at all, evidenced by the fact that the button present in it at compile time is not visible. Anyone know how to get it to show up? - thx! -Mike
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Ok I added my sub group as a skin part:
[SkinPart(required="true")]
public var group_nav_custom_comp_hgroup_prevnext:Group;
so now I can access it from anywhere in the CustomComponent. But the button inside the 'group_nav_custom_comp_hgroup_prevnext' still doesn't show up . Any one know why?
package com.viiv.digi.views.navigation
{
import mx.core.IVisualElement;
import mx.core.UIComponent;
import skins.GroupNavCustomSkin;
import spark.components.Group;
import spark.components.SkinnableContainer;
public class GroupNavCustomContainer extends SkinnableContainer
{
private var m_group_prev_next:Group = null;
private var m_bAdded_btns:Boolean = false;
private var _prevbtn:UIComponent = null;
[SkinPart(required="true")]
public var group_nav_custom_comp_hgroup_prevnext:Group;
public function GroupNavCustomContainer()
{
super();
setStyle("skinClass", GroupNavCustomSkin);
}
//----------------------------------
public function set prevBtn(ui_comp_prev:UIComponent):void
{
_prevbtn = ui_comp_prev;
m_bAdded_btns = true;
invalidateProperties();
}
//------------------------------------
public function get prevBtn():UIComponent
{
return _prevbtn;
}
//-------------------------------------------------------------------- -----
override protected function partAdded(partName:String, instance:Object):void
{
trace("In partAdded");
super.partAdded(partName, instance);
}
//-------------------------------------------------------------------- ----
override protected function commitProperties():void
{
super.commitProperties();
if (m_bAdded_btns)
{
m_bAdded_btns = false;
group_nav_custom_comp_hgroup_prevnext.addElement(_prevbtn);
}
}
}
}

The contentGroup should contain the elements added to the SkinnableContainer, and nothing else. This is managed in the parent component, not the skin. So you would add the "group_nav_custom_comp_hgroup_prevnext" Group component definition right below the contentGroup and then reference it in the GroupNavCustomContainer.

Related

Display only text field of Numeric Stepper in Flex

Is there any property of Numeric Stepper in Flex which can be used to display only the text field of Numeric Stepper and hide the arrow buttons? I need to display the complete Numeric Stepper on Mouse Roll over.
In flex 4 create custom skin with new state: over. Create new class NumericStepperExtends extends NumericStepper, listen rollover and rollout events, and change skin state.
NumericStepperExtends:
package classes
{
import flash.events.MouseEvent;
import spark.components.NumericStepper;
public class NumericStepperExtends extends NumericStepper
{
private var _over:Boolean = false;
public function NumericStepperExtends()
{
super();
}
override protected function createChildren():void
{
super.createChildren();
addEventListener(MouseEvent.ROLL_OVER, onRollOverHandler, false, 0, true);
addEventListener(MouseEvent.ROLL_OUT, onRollOutHandler, false, 0, true);
}
override protected function getCurrentSkinState():String
{
if (_over) return "over";
return super.getCurrentSkinState();
}
protected function onRollOutHandler(event:MouseEvent):void
{
_over = false;
invalidateSkinState();
}
protected function onRollOverHandler(event:MouseEvent):void
{
_over = true;
invalidateSkinState();
}
}
}
Skin:
<?xml version="1.0" encoding="utf-8"?>
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:fb="http://ns.adobe.com/flashbuilder/2009" minHeight="23" minWidth="40"
alpha.disabled="0.5">
<fx:Metadata>
<![CDATA[
[HostComponent("spark.components.NumericStepper")]
]]>
</fx:Metadata>
<fx:Script fb:purpose="styling">
static private const exclusions:Array = ["textDisplay", "decrementButton", "incrementButton"];
/**
* #private
*/
override public function get colorizeExclusions():Array {return exclusions;}
/**
* #private
*/
override protected function initializationComplete():void
{
useChromeColor = true;
super.initializationComplete();
}
private var cornerRadiusChanged:Boolean;
private var borderStylesChanged:Boolean;
/**
* #private
*/
override protected function commitProperties():void
{
super.commitProperties();
if (cornerRadiusChanged)
{
var cr:Number = getStyle("cornerRadius");
if (incrementButton)
incrementButton.setStyle("cornerRadius", cr);
if (decrementButton)
decrementButton.setStyle("cornerRadius", cr);
cornerRadiusChanged = false;
}
if (borderStylesChanged)
{
textDisplay.setStyle("borderAlpha", getStyle("borderAlpha"));
textDisplay.setStyle("borderColor", getStyle("borderColor"));
textDisplay.setStyle("borderVisible", getStyle("borderVisible"));
borderStylesChanged = false;
}
}
/**
* #private
*/
override public function styleChanged(styleProp:String):void
{
var allStyles:Boolean = !styleProp || styleProp == "styleName";
super.styleChanged(styleProp);
if (allStyles || styleProp == "cornerRadius")
{
cornerRadiusChanged = true;
invalidateProperties();
}
if (allStyles || styleProp.indexOf("border") == 0)
{
borderStylesChanged = true;
invalidateProperties();
}
}
</fx:Script>
<s:states>
<s:State name="normal" />
<s:State name="disabled" />
<s:State name="over" />
</s:states>
<s:Button id="incrementButton" right="0" top="0" height="50%" tabEnabled="false"
includeInLayout.normal="false" visible.normal="false" includeInLayout.over="true"
skinClass="spark.skins.spark.NumericStepperIncrementButtonSkin" />
<s:Button id="decrementButton" right="0" bottom="0" height="50%" tabEnabled="false"
includeInLayout.normal="false" visible.normal="false" includeInLayout.over="true"
skinClass="spark.skins.spark.NumericStepperDecrementButtonSkin" />
<s:TextInput id="textDisplay" left="0" top="0" right="18" bottom="0"
skinClass="spark.skins.spark.NumericStepperTextInputSkin" />
</s:SparkSkin>
Don't forget add css for bind new component and new skin:
<fx:Style>
#namespace s "library://ns.adobe.com/flex/spark";
#namespace mx "library://ns.adobe.com/flex/mx";
#namespace classes "classes.*";
classes|NumericStepperExtends
{
skinClass: ClassReference("skins.NumericStepper");
}
</fx:Style>
you can create a mask (tutorial here), what is applied when mouse is not over.
so you have to:
1) create a masking object,
2) mask the stepper (stepper.mask = mymask)
3) add rollover and rollout listeners to mask, where you set or remove the mask.
You can try a very simple way: Use mx_internal:
var n : NumericStepper = new NumericStepper();
n.mx_internal::nextButton.visible = false;
n.mx_internal::prevButton.visible = false;

How avoid focus on a control in Flex?

I have a Custom Component the parent is Group with Horizontal layout, in that i have two controls one is TextInput and other is datefield. When use this custom component in ant place i provide tabindex to that control as a whole.
I want just that if user tab(keyborad) then when focus on the Textinput the focus does't on dateField.
How i achieve this.
Here is my Code.
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" width="100%" height="20"
xmlns:components="com.zigron.controls.extended.components.*"
creationComplete="creComp()">
<!--
Author : Tahir Alvi
Date : 11/06/2012
Place : Zigron Inc
-->
<fx:Declarations>
<mx:DateFormatter id="formatter" formatString="MM/DD/YYYY" />
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.controls.TextInput;
import mx.events.CalendarLayoutChangeEvent;
import spark.events.TextOperationEvent;
private var _selectedDate:Date;
private var _text:String='';
private var _propmt:String='DOB';
//---- creation Complete ----------
private function creComp():void
{
id_dob.tabIndex = tabIndex;
}
//--At the initlize of datefield hide the Textinput ---
protected function init():void
{
var tf:TextInput = df.mx_internal::getTextInput();
tf.visible = false;
tf.includeInLayout = false;
}
//-- date change handler ---
protected function df_changeHandler(event:CalendarLayoutChangeEvent):void
{
id_dob.text = formatter.format(df.selectedDate.toString());
text = id_dob.text;
selectedDate = df.selectedDate;
}
// -- Text Input Change handler and apply masking on it -------
protected function id_txt_changeHandler(event:TextOperationEvent):void
{
var s:String = id_dob.text.replace(/[^0-9]/g,"");
id_dob.text = s.substring(0,2) + (s.length>2?"/"+s.substring(2,4) + (s.length>4?"/"+s.substring(4,8):""):"");
id_dob.selectRange(id_dob.text.length, id_dob.text.length);
text = id_dob.text;
if(text.length)
{
selectedDate = null;
}
else
{
text = '';
}
}
[Bindable]
public function get selectedDate():Date
{
return _selectedDate;
}
public function set selectedDate(value:Date):void
{
_selectedDate = value;
}
[Bindable]
public function get text():String
{
return _text;
}
public function set text(value:String):void
{
_text = value;
if(_text.length)
id_dob.text = _text;
}
[Bindable]
public function get propmt():String
{
return _propmt;
}
public function set propmt(value:String):void
{
_propmt = value;
}
]]>
</fx:Script>
<s:layout>
<s:HorizontalLayout horizontalAlign="left" verticalAlign="top" gap="2"/>
</s:layout>
<components:LabelTextInput id="id_dob"
width="100%" prompt="{propmt}" change="id_txt_changeHandler(event)"/>
<mx:DateField id="df"
initialize="init()" width="20" change="df_changeHandler(event)" selectableRange="{{rangeEnd:new Date()}}"
toolTip="Select Date of Birth" yearNavigationEnabled="true" textInputStyleName="mandatoryDateSkin"
maxYear="{new Date().getFullYear()}" minYear="1901"/>
</s:Group>
i had a similar problem with a custom component with a textinput inside him. My solution was create a public var, something like this:
//This is my component MyComponent...
[Bindable] public var fTabIndex:int = -1;
<mx:TextInput id="field" tabIndex="{fTabIndex}"/>
(Other component...)
//Other component
<mx:TextInput tabindex="1"/>
<control:MyComponent fTabIndex="2"/>
I hope it will be helpful.
set enabled = "false";
and change it in code when required.

In label, value is not displaying which is used in module

I am trying to call a function (having two parameters) of module and assign values to it.
I can see the value being assigned in trace, but the same value is not displaying when it is assigned to label.
If I directly assign the value to label. It says:
Error:1009: Null object Reference
If I use [Bindable] meta tag to that label, it won't show any runtime error but the value is also not displayed. I have searched the internet and found that the [Bindable] meta tag works as try and catch blog.
How to get value display assign to label?
Main.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:custom="com.custom.*" xmlns:local="*" creationComplete="onload()">
<mx:Script>
<![CDATA[
import modules.AModule;
import mx.events.ModuleEvent;
import mx.containers.VBox;
import mx.containers.TitleWindow;
import mx.controls.TextInput;
import mx.controls.Button;
import mx.containers.HBox;
import mx.controls.Label;
import mx.events.CloseEvent;
import mx.controls.Text;
import com.custom.CustomAlert;
import mx.controls.Alert;
import mx.containers.Canvas;
import mx.events.ItemClickEvent;
import mx.core.UIComponent;
import mx.modules.ModuleManager;
import mx.modules.IModuleInfo;
import mx.containers.Box;
import mx.controls.ProgressBar;
//private var can:Canvas;
public var titlewin:TitleWindow = new TitleWindow();
public var usern:TextInput = new TextInput();
public var passw:TextInput = new TextInput();
public var vb:VBox = new VBox();
public var hb1:HBox = new HBox();
public var hb2:HBox = new HBox();
public var hb3:HBox = new HBox();
public var nc:NetConnection;
public var bt1:Button = new Button();
private var pb:ProgressBar;
private var progressContainer:Box;
private var info:IModuleInfo;
private var module:UIComponent = null;
public var can:Canvas= new Canvas();
public function onload():void
{
var label1:Label= new Label();
var label2:Label= new Label();
label1.text="Username";
label2.text="Password ";
hb1.addChild(label1);
hb1.addChild(usern);
hb2.addChild(label2);
hb2.addChild(passw);
vb.addChild(hb1);
vb.addChild(hb2);
bt1.label="Sign In";
hb3.addChild(vb);
hb3.addChild(bt1);
titlewin.addChild(hb3);
//Title Window creation starts here
titlewin.title="Login";
titlewin.setStyle("paddingLeft",20);
titlewin.setStyle("paddingRight",20);
titlewin.setStyle("paddingTop",20);
titlewin.setStyle("paddingBottom",20);
titlewin.setStyle("borderThicknessBottom",0);
titlewin.setStyle("borderThicknessLeft",0);
titlewin.setStyle("borderThicknessRight",0);
titlewin.setStyle("borderThicknessTop",0);
titlewin.setStyle("cornerRadius",0);
titlewin.setStyle("borderColor","#D20101");
this.addChild(titlewin);
viewStack.enabled=false;
ctbb.enabled=false;
bt1.addEventListener(MouseEvent.CLICK, netconn);
}
private function onclick():void
{
if(usern.text!="")
{
this.removeChild(titlewin);
viewStack.enabled=true;
ctbb.enabled=true;
username.text=usern.text;
}
else
{
Alert.show("Please enter Username");
}
}
private function netconn(event:MouseEvent):void
{
nc = new NetConnection();
nc.connect("rtmp://localhost/loginhere",usern.text);
nc.addEventListener(NetStatusEvent.NET_STATUS, onstatushandler);
}
private function onstatushandler(event:NetStatusEvent):void
{
if(event.info.code=="NetConnection.Connect.Success")
{
status.text="Connected";
onclick();
}
if(event.info.code=="NetConnection.Connect.Rejected")
{
status.text="Rejected";
}
if(event.info.code=="NetConnection.Connect.Failed")
{
status.text="Failed";
}
}
private function JoinClick(event:MouseEvent):void{
if(viewStack.numChildren==3)
{
Alert.show("You Cant Add More Button","Alert");
}
if(viewStack.numChildren<3)
{
if(viewStack.numChildren<2)
{
can.label="Button2";
var button1:CustomButton= new CustomButton();
button1.label="Leave Table";
button1.x=300;
button1.y=200;
var txt:Text = new Text();
txt.text=can.label;
txt.x=50;
txt.y=50;
button1.addEventListener(MouseEvent.CLICK,remove2);
can.addChild(button1);
can.addChild(txt);
loadmodule();
}
else
{
can.label="Button3";
var button2:CustomButton= new CustomButton();
button2.label="Leave Table";
button2.x=300;
button2.y=200;
button2.addEventListener(MouseEvent.CLICK,remove3);
can.addChild(button2);
var txt1:Text = new Text();
txt1.text=can.label;
txt1.x=50;
txt1.y=50;
can.addChild(txt1);
}
can.setStyle("backgroundColor","0x5EA5BA");
viewStack.addChild(can);
if(viewStack.numChildren>2)
{
viewStack.selectedIndex=2;
}
else
{
viewStack.selectedIndex=1;
}
}
}
private function remove2(event:MouseEvent):void{
Alert.show("Do you want to Leave Table?","Confirmation",Alert.YES|Alert.NO,this,closeAlert2);
}
private function closeAlert2(event:CloseEvent):void{
if(event.detail==Alert.YES)
{
viewStack.removeChildAt(1);
}
}
private function remove3(event:MouseEvent):void{
if(viewStack.numChildren>2)
{
Alert.show("Do You want to leave Table?","Confirmation",Alert.YES|Alert.NO,this,closeAlert3);
}
else
{
Alert.show("Do you want to Leave Table?","Confirmation",Alert.YES|Alert.NO,this,closeAlert1);
}
}
private function closeAlert1(event:CloseEvent):void{
if(event.detail==Alert.YES)
{
viewStack.removeChildAt(1);
}
}
private function closeAlert3(event:CloseEvent):void{
if(event.detail==Alert.YES)
{
viewStack.removeChildAt(2);
}
}
private function loadmodule():void
{
pb = new ProgressBar();
pb.labelPlacement = "center";
pb.label = "Loading %3 %";
progressContainer = new Box();
progressContainer.percentWidth = 100;
progressContainer.percentHeight = 100;
progressContainer.setStyle("horizontalAlign", "center");
progressContainer.setStyle("verticalAlign", "middle");
progressContainer.addChild(pb);
can.addChild(progressContainer);
var moduleUrl:String="../bin-debug/modules/useModule.swf";
info=ModuleManager.getModule(moduleUrl);
if(info!=null)
{
info.addEventListener(ModuleEvent.READY, modEventHandler);
info.addEventListener(ModuleEvent.ERROR,modErrorHandler);
info.load();
}
}
private function modEventHandler(e:ModuleEvent):void
{
info.removeEventListener(ModuleEvent.READY, modEventHandler);
info.removeEventListener(ModuleEvent.ERROR, modErrorHandler);
can.removeAllChildren();
if(module==null)
{
module = info.factory.create() as UIComponent;
if(module!=null)
{
module.x=0;
module.y=0;
module.percentWidth=100;
module.percentHeight=100;
can.addChild(module);
if(module is AModule)
{
}
}
}
}
private function modErrorHandler(event:ModuleEvent):void {
//cleanup and display an error alert
info.removeEventListener(ModuleEvent.READY, modEventHandler);
info.removeEventListener(ModuleEvent.ERROR, modErrorHandler);
info = null;
Alert.show(event.toString(), "Error Loading Module");
unloadModule();
}
private function unloadModule():void
{
can.removeAllChildren();
if (module != null && info != null) {
info.addEventListener(ModuleEvent.UNLOAD, unloadEventHandler);
info.unload();
}
}
private function unloadEventHandler(e:ModuleEvent):void
{
info.removeEventListener(ModuleEvent.UNLOAD, unloadEventHandler);
module = null;
info = null;
}
]]>
</mx:Script>
<mx:Canvas width="700" height="400" x="166" y="32">
<mx:ViewStack id="viewStack" width="100%" height="100%">
<mx:Canvas label="Button1" backgroundColor="#5EA5BA" visible="true" id="can1" >
<local:CustomButton label="Join" click="JoinClick(event)" x="536" y="222"/>
<mx:Label x="304" y="120" text="Label" id="username"/>
<mx:Label x="304" y="55" text="Label" id="status"/>
</mx:Canvas>
</mx:ViewStack>
</mx:Canvas>
<custom:CustomControlBar x="166" y="423" id="ctbb">
<custom:CustomToggleButtonBar dataProvider="viewStack"/>
</custom:CustomControlBar>
</mx:Application>
useModule.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="508" height="218" implements="modules.AModule" backgroundColor="#F00F0F" creationComplete="addlabel();">
<mx:Script>
<![CDATA[
import mx.core.Application;
public var logsin:loginhere = new loginhere();
public function addlabel():void
{
lb1.text=logsin.username.text;
txt3.text=logsin.username.text;
trace(txt3.text);
trace(lb1.text);
}
]]>
</mx:Script>
<mx:TextInput id="txt3" x="30.5" y="10" width="79"/>
<mx:Label id="lb1" x="31.5" y="40" width="78" text="Will it Change?"/>
</mx:Module>
AModule.as (Its an interface)
package modules
{
import flash.events.IEventDispatcher;
public interface AModule extends IEventDispatcher
{
function addlabel():void;
}
}
I haven't looked through the entire code, but one thing I noticed is that you should pass the values on as parameters to the child components and use data binding to dynamically update parameters.
So in AModule.as:
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="508" height="218" implements="modules.AModule" backgroundColor="#F00F0F" creationComplete="addlabel();">
<mx:Script>
<![CDATA[
import mx.core.Application;
public var logsin:loginhere = new loginhere();
[Bindable]
public var username:String = "";
]]>
</mx:Script>
<mx:TextInput id="txt3" text="{username}" x="30.5" y="10" width="79"/>
<mx:Label id="lb1" text="{username}" x="31.5" y="40" width="78" text="Will it Change?"/>
</mx:Module>
In the method where you create the module you can then:
module.username = //var that holds username;
The point I missed was, I dint create a instance for interface in main.mxml
The var should be created in modEventHandler function In that function the below lines should be added
ichild=module as AModule;
ichild.addlabel(tt.text);
so the module gets called and the value is displayed in the label field.
Please let me know, if its wrong way of working. Thank You

How to increase horizontalgridline thickness in Flex 3

i have set horizontal gridlines between rows of a datagrid to true. But i'm unable to increase its thickness. how to do it?
There are two ways you can go about solving this. If you check the docs, DataGrid has a horizontalSeparatorSkin style. The docs state that this is undefined by default, and in which case the grid uses it's drawHorizontalLine() method to draw the lines.
So you can either set the horizontalSeparatorSkin style to your own class that extends ProgramaticSkin or extend the DataGrid class and override the drawHorizontalLine() method. Both are fairly easy to do, here's app with an example of each one:
App
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:local="*"
layout="vertical"
creationComplete="onCreationComplete()">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
protected function onCreationComplete():void
{
var dp:ArrayCollection= new ArrayCollection([ { label: "one", value: 1 }, { label: "two", value: 2 }, { label: "three", value: 3 } ]);
grid.dataProvider=dp;
customGrid.dataProvider=dp;
}
]]>
</mx:Script>
<mx:DataGrid id="grid" horizontalGridLines="true" horizontalSeparatorSkin="{HorizontalSeparatorSkin}">
<mx:columns>
<mx:DataGridColumn dataField="label" />
<mx:DataGridColumn dataField="value"/>
</mx:columns>
</mx:DataGrid>
<local:CustomGrid id="customGrid" horizontalGridLines="true" horizontalGridLineColor="#FF0000">
<local:columns>
<mx:DataGridColumn dataField="label" />
<mx:DataGridColumn dataField="value"/>
</local:columns>
</local:CustomGrid>
</mx:Application>
Programatic skin (HorizontalSeparatorSkin.as):
package
{
import flash.display.Graphics;
import mx.skins.ProgrammaticSkin;
public class HorizontalSeparatorSkin extends ProgrammaticSkin
{
public function HorizontalSeparatorSkin()
{
super();
}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
// draw a line at the bottom of the rectangle defined by
// unscaledWidth and unscaledHeight
var g:Graphics = this.graphics;
g.clear();
g.lineStyle(3, 0x00FF00); // change thickness / color here
g.moveTo(0,unscaledHeight);
g.lineTo(unscaledWidth, unscaledHeight);
}
}
}
Custom grid (CustomGrid.as):
package
{
import flash.display.Graphics;
import flash.display.Sprite;
import mx.controls.DataGrid;
import mx.controls.listClasses.ListBaseContentHolder;
public class CustomGrid extends DataGrid
{
public function CustomGrid()
{
super();
}
override protected function drawHorizontalLine(s:Sprite, rowIndex:int, color:uint, y:Number):void
{
var contentHolder:ListBaseContentHolder = s.parent.parent as ListBaseContentHolder;
var g:Graphics = s.graphics;
g.lineStyle(3, color); // change the thickness here
g.moveTo(0, y);
g.lineTo(contentHolder.width, y);
}
}
}

Using itemRenderer in mx Datagrid

I have a mx DataGrid with 2 column. The first column has its data rendered in a TextInput and the second column renderer in a ComboBox. When I change the selected value in the ComboBox, I want the TextInput of the same index to have its text changed to the value selected in the ComboBox. Can anyone help me with this? My code is below.
<mx:DataGrid id="myGrid" rowHeight="25" dataProvider="{Testarray}" width="100%" height="205" chromeColor="#D0CCAF" headerHeight="0" showHeaders="false" >
<mx:columns>
<mx:DataGridColumn headerText="My Header 1"
editable="true"
dataField="LBL"
>
<mx:itemRenderer>
<fx:Component>
<mx:HBox horizontalAlign="left" horizontalScrollPolicy="off" verticalScrollPolicy="off">
<s:TextInput id="label_txt" text="{data.LBL}" width="98%"/>
</mx:HBox>
</fx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
<mx:DataGridColumn headerText="My Header 2"
editable="true"
rendererIsEditor="true"
dataField="ALIAS"
>
<mx:itemRenderer>
<fx:Component>
<renderers:comboItemRenderer height="80%" change="comboitemrenderer1_changeHandler(event)" lookupField="ALIAS" labelField="ALIAS" dataProvider="{outerDocument.searchCustomizationComponents_array}">
<fx:Script>
<![CDATA[
import mx.events.DataGridEvent;
import mx.events.ListEvent;
protected function comboitemrenderer1_changeHandler(event:ListEvent):void
{
//WHAT TO PUT HERE?
}
]]>
</fx:Script>
</renderers:comboItemRenderer>
</fx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
</mx:columns>
</mx:DataGrid>
I got it myself. Thanks buddies.
I needed to add these 2 lines of codes for the textInput to take the value of the selectedItem int he ComboBox.
protected function comboitemrenderer1_changeHandler(event:ListEvent):void
{
outerDocument.myGrid.dataProvider[outerDocument.myGrid.selectedIndex]['LBL'] = this.selectedItemKey;
outerDocument.myGrid.invalidateList();
}
Also note that the code for my comboitemrenderer below:
<mx:ComboBox
xmlns:mx="http://www.adobe.com/2006/mxml"
dataChange="setSelected()"
change="onSelectionChange(event)"
focusEnabled="true">
<mx:Script>
<![CDATA[
import mx.events.DataGridEvent;
import mx.events.ListEvent;
import mx.controls.dataGridClasses.DataGridListData;
private var _ownerData:Object;
private var _lookupField:String = "value";
// When using this component as an itemEditor rather than an itemRenderer
// then set ' editorDataField="selectedItemKey"' on the column to
// ensure that changes to the ComboBox are propogated.
[Bindable] public var selectedItemKey:Object;
public function set lookupField (value:String) : void {
if(value) {
_lookupField = value;
setSelected();
}
}
override public function set data (value:Object) : void {
if(value) {
_ownerData = value;
setSelected();
}
}
override public function get data() : Object {
return _ownerData;
}
private function setSelected() : void {
if (dataProvider && _ownerData) {
var col:DataGridListData = DataGridListData(listData);
for each (var dp:Object in dataProvider) {
if (dp[_lookupField] == _ownerData[col.dataField]) {
selectedItem = dp;
selectedItemKey = _ownerData[col.dataField];
return;
}
}
}
selectedItem = null;
}
private function onSelectionChange (e:ListEvent) : void {
if (selectedItem && _ownerData) {
var col:DataGridListData = DataGridListData(listData);
_ownerData[col.dataField] = selectedItem[_lookupField];
selectedItemKey = selectedItem[_lookupField];
}
}
]]>
</mx:Script>
</mx:ComboBox>