zoukankan      html  css  js  c++  java
  • Flex PropertyGrid 实现

    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

    显示效果:

     

    Creative Commons License

    本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名孙镜涛(包含链接),具体操作方式可参考此处。如您有任何疑问或者授权方面的协商,请给我留言

  • 相关阅读:
    [sql]mysql启停脚本
    [sh]函数+条件表达式
    【Qt开发】QT中显示图像数据
    【Qt开发】QT中显示图像数据
    【Qt开发】如何将内存图像数据封装成QImage V1
    【Qt开发】如何将内存图像数据封装成QImage V1
    【Qt开发】将内存图像数据封装成QImage V2
    【Qt开发】将内存图像数据封装成QImage V2
    【Qt开发】Qt中图像的显示与基本操作
    【Qt开发】Qt中图像的显示与基本操作
  • 原文地址:https://www.cnblogs.com/jingtao/p/1762216.html
Copyright © 2011-2022 走看看