[转载]Flex PropertyGrid 实现

[转载]Flex PropertyGrid 实现 – 镜涛的家 JT – 博客园.

PropertyGrid在界面设计工具中是比较常用的组件,在.NET的WinForm设计中,PropertyGrid作为内置的组件来实现对 button、label等组件的属性设置,不仅满足了设计时的需要,还能够在运行时提供美观实用的帮助;但是Flex作为目前界面设计展现方向上的主流 技术,并没有提供该组件。为了弥补这一不足,本文将介绍并实现Flex PropertyGrid组件模型。

PropertyGrid模型可以分为两个部分,即行为模型和数据展现模型。

所谓的行为模型就是PropertyGrid所包含的事件及其在不同状态下的展示方式。事件部分我们暂且只支持PropertyGrid的 selectedObjectChanged事件。展示方式主要是悬浮状态下,Mini选项卡开启,鼠标移到Mini选项卡的时候 PropertyGrid主面板弹出,鼠标移出PropertyGrid时,PropertyGrid自动关闭,同时显示出Mini选项卡,;非悬浮状态 下,PropertyGrid停靠在Container中,Mini选项卡关闭。

数据展现模型就是PropertyGrid所展示内容的元数据定义,用这些定义好的元数据标记数据类型后,PropertyGrid可以自动的从数 据类型实例中读取元数据定义,并根据类别、描述等信息自动展示。

事件模型处理相关代码如下

[Event(name=“selectedObjectChanged”,type=“propertygrid.PropertyGridEvent”)]

[Event(name=“floatStateChanged”,type=“propertygrid.PropertyGridEvent”)];

public class IPropertyGrid extends Canvas

{

//是否 悬浮

private var isFloat:Boolean=false;

//悬浮 状态需要的mini属性卡

private var miniPropertyGird:Canvas=null;

//当前 选择对象

private var selectedObject:Object=null;

//属性 窗口容器

public var container:DisplayObjectContainer=null;

//属性 窗口内容展示区

public var content:VBox=null;

//悬浮 状态切换图片

public var title_img_pin:Image=null;

//最小 化图片

public var title_img_min:Image=null;

/**

* 构造函数

* */

public function IPropertyGrid()

{

this.addEventListener(FlexEvent.CREATION_COMPLETE,init);

this.addEventListener(PropertyGridEvent.FLOAT_STATE_CHANGED,floateStateChangedHandler);

}

/**

* 悬浮状态切换的处理函数

*

* 逻辑:悬浮状态,从容器中移除属性窗口,将mini属性窗口增加到容器中,同时为属性窗口增加Rollout处理函数

* 内嵌状态,将属性窗口增加到容器,从容器中mini属性窗口,移除属性窗口的Rollout处理函数

* */

public function floateStateChangedHandler(e:PropertyGridEvent):void

{

if(isFloat)

{

this.container.removeChild(this);

this.container.addChild(miniPropertyGird);

this.addEventListener(MouseEvent.ROLL_OUT,mouseClosePropGrid);

}

else

{

this.container.addChild(this);

this.container.removeChild(miniPropertyGird);

this.removeEventListener(MouseEvent.ROLL_OUT,mouseClosePropGrid);

}

}

/**

* 获取当前选中对象

* */

public function get SelectedObj():Object

{

return this.selectedObject;

}

/**

* 更改当前选中对象,并触发SELECTED_OBJECT_CHANGED事件

* */

public function set SelectedObj(obj:Object):void

{

if(this.selectedObject!=obj)

{

this.selectedObject=obj;

dispatchEvent(new PropertyGridEvent(PropertyGridEvent.SELECTED_OBJECT_CHANGED));

}

}

/**

* 初始化函数

* */

public function init(e:FlexEvent):void

{

Assert.notNull(container,“container”);

Assert.notNull(content,“content”);

Assert.notNull(title_img_pin,“title_img_pin”);

Assert.notNull(title_img_min,“title_img_min”);

title_img_pin.addEventListener(MouseEvent.CLICK,changeFloatState);

title_img_min.addEventListener(MouseEvent.CLICK,minPropertyGrid);

initMiniPropertyGrid();

}

/**

* 更改悬浮状态函数

* */

public function changeFloatState(e:MouseEvent):void

{

this.isFloat=!this.isFloat;

dispatchEvent(new PropertyGridEvent(PropertyGridEvent.FLOAT_STATE_CHANGED));

}

/**

* 悬浮状态下显示属性窗口函数

* */

public function showPropertyGrid(e:MouseEvent):void

{

var point:Point=new Point(container.x+container.width-this.width,container.y);

var targetPoint:Point=container.localToGlobal(point);

this.x=targetPoint.x;

this.y=targetPoint.y;

this.height=container.height;

PopUpManager.addPopUp(this,container,false);

var effect:WipeLeft=new WipeLeft();

effect.duration=300;

effect.target=this;

effect.play();

}

/**

* 初始化mini属性窗口

* */

public function initMiniPropertyGrid():void

{

miniPropertyGird=new Canvas();

miniPropertyGird.height=100;

miniPropertyGird.width=25;

miniPropertyGird.setStyle(“top”,0);

miniPropertyGird.setStyle(“right”,0);

var img:Image=new Image();

img.source=“assets/propertygrid.png”;

img.percentHeight=100;

img.percentWidth=100;

img.addEventListener(MouseEvent.MOUSE_OVER,showPropertyGrid);

miniPropertyGird.addChild(img);

}

/**

* 最小化属性窗口函数

* */

public function minPropertyGrid(e:MouseEvent):void

{

PopUpManager.removePopUp(this);

}

/**

* 关闭悬浮状态属性窗口处理函数

* */

public function mouseClosePropGrid(e:MouseEvent):void

{

var pg:IPropertyGrid=e.target as IPropertyGrid;

if(pg!=null)

{

PopUpManager.removePopUp(pg);

}

}

/**

* 增加属性窗口单元

*

* @param title:单元标题

* */

public function addGridUnit(title:String):GridUnit

{

var tgrid:GridUnit=new GridUnit();

PopUpManager.addPopUp(tgrid,Application.application.document);

tgrid.title_content.text=title;

this.content.addChild(tgrid);

return tgrid;

}

}

/**

* @desc: 属性窗口事件

*     SELECTED_OBJECT_CHANGED 当前选中对象改变时触发的事件

*     FLOAT_STATE_CHANGED 悬浮状态发生改变时触发的事件

*

* @author:    sunjingtao

* */

public class PropertyGridEvent extends Event

{

public static const SELECTED_OBJECT_CHANGED:String=“selectedObjectChanged”;

public static const FLOAT_STATE_CHANGED:String=“floatStateChanged”;

public function PropertyGridEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)

{

super(type, bubbles, cancelable);

}

}

数据模型部分想要做好就比较复杂,但是主要就是反射相关知识以 及元数据的使用

反射:describeType函数

元数据:编译时增加编 译参数-keep-as3-metadata+=MetaData1,MetaData2…

使用

假设我们对以下对象进 行属性设置:

public class Activity

{

[Appearance(name=“imageSource”,description=图像资源)]

public var ImageSource:String;

[Behavior(name=“do1”,description=行为)]

public var DoEvent1:String;

[Behavior(name=“do2”,description=行为)]

public var DoEvent2:String;

public var Test:String;

public function Activity(source:String,doEvent:String)

{

this.ImageSource=source;

this.DoEvent1=doEvent+“11”;

this.DoEvent2=doEvent+“22”;

}

}

主程序为:

<?xml version=”1.0″ encoding=”utf-8″?>

<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” layout=”absolute

xmlns:propertygrid=”ui.propertygrid.*>

<mx:Script>

<![CDATA[

import datastructure.Map;

import mx.managers.PopUpManager;

import ui.propertygrid.GridUnit;

import mx.controls.Label;

import mx.containers.GridItem;

import mx.containers.GridRow;

import mx.collections.ArrayCollection;

import reflect.MetaDataInfo;

import reflect.MetaData;

import mx.containers.FormItem;

import reflect.Variable;

import reflect.InstanceInfo;

import flash.utils.describeType;

import xdesigner.Activity;

private function doParse():void

{

var act:Activity=new Activity(“source”,“doEvent”);

var instance:MetaDataInfo=new MetaDataInfo(act);

for each(var key:String in instance.Keys)

{

var tgrid:GridUnit=propgrid.addGridUnit(key);

for each(var obj:Object in instance.getMetaDataRefObjs(key))

{

if(obj is Variable)

{

var variable:Variable=obj as Variable;

var map:Map=new Map();

map.push(“text”,variable.Value);

tgrid.addRow(variable.Name,new Label(),map);

}

}

}

}

]]>

</mx:Script>

<mx:Canvas id=”container” width=”100%” height=”100%>

<mx:Canvas width=”100%” height=”100%” borderStyle=”solid” borderColor=”#F5F7F9>

<propertygrid:PropertyGrid id=”propgrid” container=”{container}” x=”81” y=”31>

</propertygrid:PropertyGrid>

</mx:Canvas>

</mx:Canvas>

<mx:Button label=”Parse” click=”doParse()”/>

</mx:Application>

原创文章,转载请注明出处!
All CopyRight Reserved

主页:http://jingtao.cnblogs.com

QQ:307073463
Email:jingtaodeemail@qq.com
MSN:sunjingtao@live.com

显示效果:

赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏