rightclickmanager 双击弹出窗口 右键屏蔽问题 flex 右键

本文介绍了一种在Flex应用程序中实现自定义右键菜单的方法。该方法通过封装RightClickManager类来屏蔽系统默认的右键菜单,并允许开发者根据需要动态生成自定义菜单项。适用于需要远程交互和权限控制的应用场景。

网上关于 rightclickmanager 类似的 flex 自定义右键文章数不胜数.

 

但是选择的话.还需要根据每个用户的操作来选择使用那一种方式.

 

比如这个

Flex屏蔽并自定义鼠标右键菜单

就是别人自己封装了rightclickmanager并且扩展了一些功能. 将用户的代码工作量减低减少

 

但是有一点 : 过多的封装就降低了灵活性, 这种类型有个局限性, 就是如果需要在点击右键通过远程方法

 

来设置右键信息. 比如使用cairngorm远程调用java来返回右键的菜单和ennable等信息时,就不适用了

 

这个时候就需要另一个

 

FLEX 屏闭系统右键菜单,及在列表控件DataGrid\Tree\List上点右键时自动选择当前行

虽说好是好. 每个人都做过改动. 这点大家要看清. 适合别人的并不一定就是最适合自己的. 像这个封装的不多. 但是如果要添加右键的话 . 代码的工作量相比上一个就多了.  如果您的工程远程交互比较强, 右键信息需要在运行时动态改变. 就得自己再做一些修改了.

 

 

 

------------------------------------------------------------------------------------------------------------------------

 

 

放上自己修改的 rightclickmanager  代码, 没有过多封装,比较灵活. 也减少了页面载入的代码量.

 

就两个类  RightClickManager.as  和 RightClickRegister.as(这个是将第一个例子的代码拿来使用,拿来主义么. 减少代码量)

 

RightClickManager.as

 

 

package com.thams.contextMenu.utils
{
	import flash.display.DisplayObject;
	import flash.events.MouseEvent;
	import flash.external.ExternalInterface;
	
	import mx.controls.listClasses.IListItemRenderer;
	import mx.core.Application;
	
	public class RightClickManager
	{
		static private var rightClickTarget:DisplayObject;
		static public const RIGHT_CLICK:String = "rightClick";
		static private const javascript:XML = 
			<script>
				<![CDATA[
					function(flashObjectId)
					{				
						var RightClick = {
							init: function (flashObjectId) {
								this.FlashObjectID = flashObjectId;
								this.Cache = this.FlashObjectID;
								if(window.addEventListener){
									 window.addEventListener("mousedown", this.onGeckoMouse(), true);
								} else {
									document.getElementById(this.FlashObjectID).parentNode.onmouseup = function() { document.getElementById(RightClick.FlashObjectID).parentNode.releaseCapture(); }
									document.oncontextmenu = function(){ if(window.event.srcElement.id == RightClick.FlashObjectID) { return false; } else { RightClick.Cache = "nan"; }}
									document.getElementById(this.FlashObjectID).parentNode.onmousedown = RightClick.onIEMouse;
								}
							},
							killEvents: function(eventObject) {
								if(eventObject) {
									if (eventObject.stopPropagation) eventObject.stopPropagation();
									if (eventObject.preventDefault) eventObject.preventDefault();
									if (eventObject.preventCapture) eventObject.preventCapture();
									if (eventObject.preventBubble) eventObject.preventBubble();
								}
							},
							onGeckoMouse: function(ev) {
								return function(ev) {
								if (ev.button != 0) {
									RightClick.killEvents(ev);
									if(ev.target.id == RightClick.FlashObjectID && RightClick.Cache == RightClick.FlashObjectID) {
										RightClick.call();
									}
									RightClick.Cache = ev.target.id;
								}
							  }
							},
							onIEMouse: function() {
								if (event.button ==2||event.button==0) {
									if(window.event.srcElement.id == RightClick.FlashObjectID && RightClick.Cache == RightClick.FlashObjectID) {
										RightClick.call(); 
									}
									document.getElementById(RightClick.FlashObjectID).parentNode.setCapture();
									if(window.event.srcElement.id)
									RightClick.Cache = window.event.srcElement.id;
								}
							},
							call: function() {
									document.getElementById(this.FlashObjectID).rightClick();
							}
						}
						
						RightClick.init(flashObjectId);
					}
				]]>
			</script>;
		
		public function RightClickManager()
		{
			return;
		}
		
		static public function regist() : Boolean
		{
			if (ExternalInterface.available)
			{
				ExternalInterface.call(javascript, ExternalInterface.objectID);
				ExternalInterface.addCallback("rightClick", dispatchRightClickEvent);
				Application.application.addEventListener(MouseEvent.MOUSE_OVER,mouseOverHandler);
			}// end if
			return true;
		}
		
		static private function mouseOverHandler(event:MouseEvent) : void
		{
			rightClickTarget = DisplayObject(event.target);
			//trace(rightClickTarget.name);
			//rightClickTarget = (rightClickTarget is IListItemRenderer)?rightClickTarget:null; // 如果不是在列表上,则取消右键事件
			return;
		}
		static private function dispatchRightClickEvent() : void
		{
			var event:MouseEvent;
			if (rightClickTarget != null)
			{	
				//trace(rightClickTarget)
				event = new MouseEvent(RIGHT_CLICK, true,false, rightClickTarget.mouseX, rightClickTarget.mouseY);
				rightClickTarget.dispatchEvent(event);
			}// end if
			return;
		}
		//添加在不希望出现右键菜单比如弹出窗口上 .执行即可
		static public function setRightClickTargetNULL():void{
			rightClickTarget = null;
		}
		
		
	}
}
  

 

 

 

setRightClickTargetNULL 方法 是本人添加的一个方法. 因为遇到这么一个问题.

一个datagrid 列表. 需要显示右键 , 其他都正常. 但是如果在条目上双击打开一个弹出窗口后.因为鼠标上次悬停对象仍然是datagird , 碰巧. 弹出窗口又是遮罩的(遮罩层无法获取鼠标over事件).这样 rightClickTarget 这个对象就是上次那个对象不为空. 这个时候.在弹出窗口上右键点击. 还会出现.

 

所以本人增加了这么一个方法. 在需要屏蔽右键的 PopUpManager 之前.调用一下

 

RightClickManager.setRightClickTargetNULL();// 设置弹出窗口上的右键信息失效

 例如本人的双击方法:

 

 

			/**
			 * 双击执行事件
			 */
			protected function dataDoubleClickFunction():void
			{
				RightClickManager.setRightClickTargetNULL();// 设置弹出窗口上的右键信息失效
				var _index:Index = this.parentApplication as Index;
				if(_index.currentState=="sjzbState"||_index.currentState=="daglState"){
					_index.sjzbMain.dataGridFrame.setDtableGridObject(dtableGrid);
					_index.sjzbMain.dataGridFrame.edit();
				}
				
			}
 

 

 

这样就防止了如果在鼠标没有移出监听区域打开一个遮罩窗口. 右键还存在的一个bug.

 

 

RightClickRegister.as

 

package com.thams.contextMenu.utils
{
	import flash.display.Sprite;
	
	import mx.utils.NameUtil;
	
	[Event(name="rightClick",type="flash.events.MouseEvent")]
	public dynamic class RightClickRegister extends Sprite
	{
		private var rightClickRegisted:Boolean = false;

        public function RightClickRegister()
        {
            if (!rightClickRegisted)
            {
                RightClickManager.regist();
                rightClickRegisted = true;
            }
            try
            {
                name = NameUtil.createUniqueName(this);
            }
            catch (e:Error)
            {
            }
            return;
        }

        public override function toString() : String
        {
            return NameUtil.displayObjectToString(this);
        }

	}
}

 这个类没什么好说的. 拿来主义 . 嘿嘿

 

 

下面说下如何使用:

 

因为只要注册过一次监听后. 整个工程的右键就都会屏蔽 .故本人推荐.直接在application中屏蔽掉算. (反正右键迟早都是要屏蔽的.换成自己的右键)

 

1. 在application 初始化方法中 new 一个RightClickRegister

 

例如:

private function init():void{
				new RightClickRegister(); 
				var br:IBrowserManager = BrowserManager.getInstance();
				br.setTitle("王^林**系统");
			}

 这样这个application种(相信您的工程不会有多个应用吧. 有的话.就在需要屏蔽右键的地方加上这么一句话)

 

2. 在需要自定义右键的地方 加入监听

 

 

this.addEventListener(RightClickManager.RIGHT_CLICK,rightClickHandler);

 

 

事件:

本人这里右键是通过 模块不同. 和选择的数据条目不同. 去后台判断权限生成右键的.所以右键定义在 cairngorm的回调方法中

 

protected function rightClickHandler(event:MouseEvent):void  
			{  
				removeMenu();  
				var label:String;
				if(dtableGrid.dataLoaderClass.attr == 0){
					label = "档案管理";
				}
				if(dtableGrid.dataLoaderClass.attr == 1){
					label = "收集整编";
				}
				CairngormEventDispatcher.getInstance().dispatchEvent(new ContextMenuClassEvent(label,dtableGrid.selectedItems,contextMenuInitData));
			}

 

cairngorm的回调方法:

 

private function contextMenuInitData(contextMenuItems:ArrayCollection):void{
				//contextMenuItems 是从后台获取的右键Array集合,即右键信息
				menu = Menu.createMenu(this, contextMenuItems, false);  
				
				menu.labelField="caption"   
				menu.variableRowHeight = true;     
				//menu.addEventListener(MenuEvent.ITEM_CLICK, menuItemClickHandler);       
				
//				var point:Point = new Point(mouseX,mouseY);  
//				point = localToGlobal(point);   
				menu.show(stage.mouseX,stage.mouseY);   
				
			}

 如果您不嫌麻烦的话. 还是在页面上写个方法吧. 不希望在页面上点击多次右键. 出现一堆右键吧

 

/** 
			 * 如果显示过Menu,则先释放资源 
			 *  
			 */       
			private function removeMenu():void  
			{  
				if(menu!=null)  
				{  
					menu.hide();  
					//menu.removeEventListener(MenuEvent.ITEM_CLICK,menuItemClickHandler);  
					menu=null;  
				}  
			}  
			

 

到此就完了. 还是那句话. 没有最适合您的. 只有自己动手.丰衣足食

 

贴上几个右键图片效果

 

 

两个右键判断权限后.菜生成的. 对比下效果

 



 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值