介绍
给GridView的数据行增加右键菜单可以增加用户体验,不过实现起来挺麻烦的,现在我们扩展一下GridView控件以实现这样的功能。
控件开发
1、新建一个继承自GridView的类。
2、新建一个ContextMenu实体类,有六个属性
3、新建一个继承自CollectionBase的类ContextMenus
4、在继承自GridView的类中加一个复杂对象属性,该复杂对象就是第3步创建的那个ContextMenus
5、新建一个JavaScriptConstant类,把我们要用到的javascript存在一个常量里
6、重写OnPreRender方法,注册上面那段客户端脚本
7、重写OnRowDataBound给数据行增加客户端代码以调用我们注册的那段javascript,从而实现给GridView的数据行增加右键菜单的功能。
控件使用
添加这个控件到工具箱里,然后拖拽到webform上,设置如下属性:ItemType为右键菜单的项的类别(Link,Command,Separator);Icon为文字左边的图标的链接;Text为菜单的文字;CommandButtonId为所调用的命令按钮的ID;NavigateUrl为链接的url;Target为链接的target(Blank,Self,Top)
ObjData.cs
Default.aspx
注:如果想修改右键菜单的样式,请自行修改javascript,我就不把他们弄出来了。
给GridView的数据行增加右键菜单可以增加用户体验,不过实现起来挺麻烦的,现在我们扩展一下GridView控件以实现这样的功能。
控件开发
1、新建一个继承自GridView的类。
/**/
/// <summary>
/// 继承自GridView
/// </summary>
[ToolboxData( @" <{0}:SmartGridView runat='server'></{0}:SmartGridView> " )]
public class SmartGridView : GridView
{
}
/// 继承自GridView
/// </summary>
[ToolboxData( @" <{0}:SmartGridView runat='server'></{0}:SmartGridView> " )]
public class SmartGridView : GridView
{
}
2、新建一个ContextMenu实体类,有六个属性
using
System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Web.UI;
namespace YYControls.SmartGridView
{
/**//// <summary>
/// ContextMenu 的摘要说明。
/// </summary>
[ToolboxItem(false)]
public class ContextMenu
{
private string _icon;
/**//// <summary>
/// 文字左边的图标的链接
/// </summary>
public string Icon
{
get { return _icon; }
set { _icon = value; }
}
private string _text;
/**//// <summary>
/// 菜单的文字
/// </summary>
public string Text
{
get { return _text; }
set { _text = value; }
}
private string _commandButtonId;
/**//// <summary>
/// 所调用的命令按钮的ID
/// </summary>
public string CommandButtonId
{
get { return _commandButtonId; }
set { _commandButtonId = value; }
}
private string _navigateUrl;
/**//// <summary>
/// 链接的url
/// </summary>
public string NavigateUrl
{
get { return _navigateUrl; }
set { _navigateUrl = value; }
}
private ItemTypeCollection _itemType;
/**//// <summary>
/// 右键菜单的项的类别
/// </summary>
public ItemTypeCollection ItemType
{
get { return _itemType; }
set { _itemType = value; }
}
private TargetCollection _target;
/**//// <summary>
/// 链接的target
/// </summary>
public TargetCollection Target
{
get { return _target; }
set { _target = value; }
}
/**//// <summary>
/// 右键菜单的项的类别
/// </summary>
public enum ItemTypeCollection
{
/**//// <summary>
/// 链接
/// </summary>
Link,
/**//// <summary>
/// 按钮
/// </summary>
Command,
/**//// <summary>
/// 分隔线
/// </summary>
Separator
}
/**//// <summary>
/// 链接的target
/// </summary>
public enum TargetCollection
{
/**//// <summary>
/// 新开窗口
/// </summary>
Blank,
/**//// <summary>
/// 当前窗口
/// </summary>
Self,
/**//// <summary>
/// 跳出框架
/// </summary>
Top
}
}
}
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Web.UI;
namespace YYControls.SmartGridView
{
/**//// <summary>
/// ContextMenu 的摘要说明。
/// </summary>
[ToolboxItem(false)]
public class ContextMenu
{
private string _icon;
/**//// <summary>
/// 文字左边的图标的链接
/// </summary>
public string Icon
{
get { return _icon; }
set { _icon = value; }
}
private string _text;
/**//// <summary>
/// 菜单的文字
/// </summary>
public string Text
{
get { return _text; }
set { _text = value; }
}
private string _commandButtonId;
/**//// <summary>
/// 所调用的命令按钮的ID
/// </summary>
public string CommandButtonId
{
get { return _commandButtonId; }
set { _commandButtonId = value; }
}
private string _navigateUrl;
/**//// <summary>
/// 链接的url
/// </summary>
public string NavigateUrl
{
get { return _navigateUrl; }
set { _navigateUrl = value; }
}
private ItemTypeCollection _itemType;
/**//// <summary>
/// 右键菜单的项的类别
/// </summary>
public ItemTypeCollection ItemType
{
get { return _itemType; }
set { _itemType = value; }
}
private TargetCollection _target;
/**//// <summary>
/// 链接的target
/// </summary>
public TargetCollection Target
{
get { return _target; }
set { _target = value; }
}
/**//// <summary>
/// 右键菜单的项的类别
/// </summary>
public enum ItemTypeCollection
{
/**//// <summary>
/// 链接
/// </summary>
Link,
/**//// <summary>
/// 按钮
/// </summary>
Command,
/**//// <summary>
/// 分隔线
/// </summary>
Separator
}
/**//// <summary>
/// 链接的target
/// </summary>
public enum TargetCollection
{
/**//// <summary>
/// 新开窗口
/// </summary>
Blank,
/**//// <summary>
/// 当前窗口
/// </summary>
Self,
/**//// <summary>
/// 跳出框架
/// </summary>
Top
}
}
}
3、新建一个继承自CollectionBase的类ContextMenus
using
System.Collections;
using System.ComponentModel;
using System.Web.UI;
namespace YYControls.SmartGridView
{
/**//// <summary>
/// ContextMenus 的摘要说明。
/// 注意要继承自CollectionBase
/// </summary>
[
ToolboxItem(false),
ParseChildren(true)
]
public class ContextMenus : CollectionBase
{
/**//// <summary>
/// 构造函数
/// </summary>
public ContextMenus()
: base()
{
}
/**//// <summary>
/// 实现IList接口
/// 获取或设置指定索引处的元素。
/// </summary>
/// <param name="index">要获得或设置的元素从零开始的索引</param>
/// <returns></returns>
public ContextMenu this[int index]
{
get
{
return (ContextMenu)base.List[index];
}
set
{
base.List[index] = (ContextMenu)value;
}
}
/**//// <summary>
/// 实现IList接口
/// 将某项添加到 System.Collections.IList 中。
/// </summary>
/// <param name="item">要添加到 System.Collections.IList 的 System.Object。</param>
public void Add(ContextMenu item)
{
base.List.Add(item);
}
/**//// <summary>
/// 实现IList接口
/// 从 System.Collections.IList 中移除特定对象的第一个匹配项。
/// </summary>
/// <param name="index">要从 System.Collections.IList 移除的 System.Object</param>
public void Remove(int index)
{
if (index > -1 && index < base.Count)
{
base.List.RemoveAt(index);
}
}
/**//// <summary>
/// ToString()
/// </summary>
/// <returns></returns>
public override string ToString()
{
return "ContextMenus";
}
}
}
using System.ComponentModel;
using System.Web.UI;
namespace YYControls.SmartGridView
{
/**//// <summary>
/// ContextMenus 的摘要说明。
/// 注意要继承自CollectionBase
/// </summary>
[
ToolboxItem(false),
ParseChildren(true)
]
public class ContextMenus : CollectionBase
{
/**//// <summary>
/// 构造函数
/// </summary>
public ContextMenus()
: base()
{
}
/**//// <summary>
/// 实现IList接口
/// 获取或设置指定索引处的元素。
/// </summary>
/// <param name="index">要获得或设置的元素从零开始的索引</param>
/// <returns></returns>
public ContextMenu this[int index]
{
get
{
return (ContextMenu)base.List[index];
}
set
{
base.List[index] = (ContextMenu)value;
}
}
/**//// <summary>
/// 实现IList接口
/// 将某项添加到 System.Collections.IList 中。
/// </summary>
/// <param name="item">要添加到 System.Collections.IList 的 System.Object。</param>
public void Add(ContextMenu item)
{
base.List.Add(item);
}
/**//// <summary>
/// 实现IList接口
/// 从 System.Collections.IList 中移除特定对象的第一个匹配项。
/// </summary>
/// <param name="index">要从 System.Collections.IList 移除的 System.Object</param>
public void Remove(int index)
{
if (index > -1 && index < base.Count)
{
base.List.RemoveAt(index);
}
}
/**//// <summary>
/// ToString()
/// </summary>
/// <returns></returns>
public override string ToString()
{
return "ContextMenus";
}
}
}
4、在继承自GridView的类中加一个复杂对象属性,该复杂对象就是第3步创建的那个ContextMenus
private
ContextMenus _contextMenus;
/**/ /// <summary>
/// 行的右键菜单集合
/// </summary>
[
PersistenceMode(PersistenceMode.InnerProperty),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
Description( " 行的右键菜单 " ),
Category( " 扩展 " )
]
public virtual ContextMenus ContextMenus
{
get
{
if (_contextMenus == null)
{
_contextMenus = new ContextMenus();
}
return _contextMenus;
}
}
/**/ /// <summary>
/// 行的右键菜单集合
/// </summary>
[
PersistenceMode(PersistenceMode.InnerProperty),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
Description( " 行的右键菜单 " ),
Category( " 扩展 " )
]
public virtual ContextMenus ContextMenus
{
get
{
if (_contextMenus == null)
{
_contextMenus = new ContextMenus();
}
return _contextMenus;
}
}
5、新建一个JavaScriptConstant类,把我们要用到的javascript存在一个常量里
using
System;
using System.Collections.Generic;
using System.Text;
namespace YYControls.SmartGridView
{
/**//// <summary>
/// javascript
/// </summary>
public class JavaScriptConstant
{
internal const string jsContextMenu = @"<script type=""text/javascript"">
//<![CDATA[
// 数据行的ClientId
var _rowClientId = '';
// 以下实现右键菜单,网上找的,不知道原创是谁
function contextMenu()
{
this.items = new Array();
this.addItem = function (item)
{
this.items[this.items.length] = item;
}
this.show = function (oDoc)
{
var strShow = '';
var i;
// 加上word-break: keep-all; 防止菜单项换行
strShow = ""<div id='rightmenu' style='word-break: keep-all;BACKGROUND-COLOR: #ffffff; BORDER: #000000 1px solid; LEFT: 0px; POSITION: absolute; TOP: 0px; VISIBILITY: hidden; Z-INDEX: 10'>"";
strShow += ""<table border='0' height='"";
strShow += this.items.length * 20;
strShow += ""' cellpadding='0' cellspacing='0'>"";
strShow += ""<tr height='3'><td bgcolor='#d0d0ce' width='2'></td><td>"";
strShow += ""<table border='0' width='100%' height='100%' cellpadding=0 cellspacing=0 bgcolor='#ffffff'>"";
strShow += ""<tr><td bgcolor='#d0d0ce' width='23'></td><td><img src=' ' height='1' border='0'></td></tr></table>"";
strShow += ""</td><td width='2'></td></tr>"";
strShow += ""<tr><td bgcolor='#d0d0ce'></td><td>"";
strShow += ""<table border='0' width='100%' height='100%' cellpadding=3 cellspacing=0 bgcolor='#ffffff'>"";
oDoc.write(strShow);
for(i=0; i<this.items.length; i++)
{
this.items[i].show(oDoc);
}
strShow = ""</table></td><td></td></tr>"";
strShow += ""<tr height='3'><td bgcolor='#d0d0ce'></td><td>"";
strShow += ""<table border='0' width='100%' height='100%' cellpadding=0 cellspacing=0 bgcolor='#ffffff'>"";
strShow += ""<tr><td bgcolor='#d0d0ce' width='23'></td><td><img src=' ' height='1' border='0'></td></tr></table>"";
strShow += ""</td><td></td></tr>"";
strShow += ""</table></div>\n"";
oDoc.write(strShow);
}
}
function contextItem(text, icon, cmd, url, target, type)
{
this.text = text ? text : '';
this.icon = icon ? icon : '';
this.cmd = cmd ? cmd : '';
this.url = url ? url : '';
this.target =target ? target : '';
this.type = type ? type : 'Link';
this.show = function (oDoc)
{
var strShow = '';
if(this.type == 'Link' || this.type == 'Command')
{
strShow += ""<tr "";
strShow += ""οnmοuseοver=\""changeStyle(this, 'on');\"" "";
strShow += ""οnmοuseοut=\""changeStyle(this, 'out');\"" "";
if (this.type == 'Command')
{
// 右键菜单是按钮类型,调用所对应的按钮的click事件
strShow += ""οnclick=\""document.getElementById("";
strShow += ""_rowClientId + "";
strShow += ""'_"";
strShow += this.cmd;
strShow += ""').click()"";
}
else
{
// 右键菜单是链接类型
if (this.target == 'Top') this.target = 'top';
if (this.target == 'Self') this.target = 'self';
if (this.target == 'top' || this.target == 'self')
{
strShow += ""οnclick=\"""";
strShow += this.target;
strShow += "".location='"";
strShow += this.url;
strShow += ""'"";
}
else
{
strShow += ""οnclick=\""window.open('"";
strShow += this.url;
strShow += ""')"";
}
}
strShow += ""\"">"";
strShow += ""<td class='ltdexit' width='16'>"";
if (this.icon == '')
{
strShow += ' ';
}
else
{
strShow += ""<img border='0' src='"";
strShow += this.icon;
strShow += ""' width='16' height='16' style='POSITION: relative'></img>"";
}
strShow += ""</td><td class='mtdexit'>"";
strShow += this.text;
strShow += ""</td><td class='rtdexit' width='5'> </td></tr>"";
}
// 右键菜单是分隔线
else if (this.type == 'Separator')
{
strShow += ""<tr><td class='ltdexit'> </td>"";
strShow += ""<td class='mtdexit' colspan='2'><hr color='#000000' size='1'></td></tr>"";
}
oDoc.write(strShow);
}
}
function changeStyle(obj, cmd)
{
if(obj)
{
try
{
var imgObj = obj.children(0).children(0);
if(cmd == 'on')
{
obj.children(0).className = 'ltdfocus';
obj.children(1).className = 'mtdfocus';
obj.children(2).className = 'rtdfocus';
if(imgObj)
{
if(imgObj.tagName.toUpperCase() == 'IMG')
{
imgObj.style.left = '-1px';
imgObj.style.top = '-1px';
}
}
}
else if(cmd == 'out')
{
obj.children(0).className = 'ltdexit';
obj.children(1).className = 'mtdexit';
obj.children(2).className = 'rtdexit';
if(imgObj)
{
if(imgObj.tagName.toUpperCase() == 'IMG')
{
imgObj.style.left = '0px';
imgObj.style.top = '0px';
}
}
}
}
catch (e) {}
}
}
function showMenu(rowClientId)
{
_rowClientId = rowClientId;
var x, y, w, h, ox, oy;
x = event.clientX;
y = event.clientY;
var obj = document.getElementById('rightmenu');
if (obj == null)
return true;
ox = document.body.clientWidth;
oy = document.body.clientHeight;
if(x > ox || y > oy)
return false;
w = obj.offsetWidth;
h = obj.offsetHeight;
if((x + w) > ox)
x = x - w;
if((y + h) > oy)
y = y - h;
// obj.style.posLeft = x + document.body.scrollLeft;
// obj.style.posTop = y + document.body.scrollTop;
// xhtml不支持上面的了
// 就是说如果你的页头声明了页是xhtml的话就不能用上面那句了,vs2005创建的aspx会默认加上xhtml声明
// 此时应该用如下的方法
obj.style.posLeft = x + document.documentElement.scrollLeft;
obj.style.posTop = y + document.documentElement.scrollTop;
obj.style.visibility = 'visible';
return false;
}
function hideMenu()
{
if(event.button == 0)
{
var obj = document.getElementById('rightmenu');
if (obj == null)
return true;
obj.style.visibility = 'hidden';
obj.style.posLeft = 0;
obj.style.posTop = 0;
}
}
function writeStyle()
{
var strStyle = '';
strStyle += ""<STYLE type='text/css'>"";
strStyle += ""TABLE {Font-FAMILY: 'Tahoma','Verdana','宋体'; FONT-SIZE: 9pt}"";
strStyle += "".mtdfocus {BACKGROUND-COLOR: #ccccff; BORDER-BOTTOM: #000000 1px solid; BORDER-TOP: #000000 1px solid; CURSOR: hand}"";
strStyle += "".mtdexit {BACKGROUND-COLOR: #ffffff; BORDER-BOTTOM: #ffffff 1px solid; BORDER-TOP: #ffffff 1px solid}"";
strStyle += "".ltdfocus {BACKGROUND-COLOR: #ccccff; BORDER-BOTTOM: #000000 1px solid; BORDER-TOP: #000000 1px solid; BORDER-LEFT: #000000 1px solid; CURSOR: hand}"";
strStyle += "".ltdexit {BACKGROUND-COLOR: #d0d0ce; BORDER-BOTTOM: #d0d0ce 1px solid; BORDER-TOP: #d0d0ce 1px solid; BORDER-LEFT: #d0d0ce 1px solid}"";
strStyle += "".rtdfocus {BACKGROUND-COLOR: #ccccff; BORDER-BOTTOM: #000000 1px solid; BORDER-TOP: #000000 1px solid; BORDER-RIGHT: #000000 1px solid; CURSOR: hand}"";
strStyle += "".rtdexit {BACKGROUND-COLOR: #ffffff; BORDER-BOTTOM: #ffffff 1px solid; BORDER-TOP: #ffffff 1px solid; BORDER-RIGHT: #ffffff 1px solid}"";
strStyle += ""</STYLE>"";
document.write(strStyle);
}
function makeMenu()
{
var myMenu, item;
myMenu = new contextMenu();
// 增加右键菜单项 开始
// item = new contextItem("", "", "", "", "", "");
// 1-菜单项的文本
// 2-图标链接
// 3-所调用的命令按钮的ID
// 4-链接地址
// 5-链接的target
// 6-右键菜单的项的类别
// myMenu.addItem(item);
[$MakeMenu$]
// 增加右键菜单项 结束
myMenu.show(this.document);
delete item;
delete myMenu;
}
function toggleMenu(isEnable)
{
if(isEnable)
document.oncontextmenu = showMenu;
else
document.oncontextmenu = new function() {return true;};
}
writeStyle();
makeMenu();
document.onclick = hideMenu;
//]]>
</script>";
}
}
using System.Collections.Generic;
using System.Text;
namespace YYControls.SmartGridView
{
/**//// <summary>
/// javascript
/// </summary>
public class JavaScriptConstant
{
internal const string jsContextMenu = @"<script type=""text/javascript"">
//<![CDATA[
// 数据行的ClientId
var _rowClientId = '';
// 以下实现右键菜单,网上找的,不知道原创是谁
function contextMenu()
{
this.items = new Array();
this.addItem = function (item)
{
this.items[this.items.length] = item;
}
this.show = function (oDoc)
{
var strShow = '';
var i;
// 加上word-break: keep-all; 防止菜单项换行
strShow = ""<div id='rightmenu' style='word-break: keep-all;BACKGROUND-COLOR: #ffffff; BORDER: #000000 1px solid; LEFT: 0px; POSITION: absolute; TOP: 0px; VISIBILITY: hidden; Z-INDEX: 10'>"";
strShow += ""<table border='0' height='"";
strShow += this.items.length * 20;
strShow += ""' cellpadding='0' cellspacing='0'>"";
strShow += ""<tr height='3'><td bgcolor='#d0d0ce' width='2'></td><td>"";
strShow += ""<table border='0' width='100%' height='100%' cellpadding=0 cellspacing=0 bgcolor='#ffffff'>"";
strShow += ""<tr><td bgcolor='#d0d0ce' width='23'></td><td><img src=' ' height='1' border='0'></td></tr></table>"";
strShow += ""</td><td width='2'></td></tr>"";
strShow += ""<tr><td bgcolor='#d0d0ce'></td><td>"";
strShow += ""<table border='0' width='100%' height='100%' cellpadding=3 cellspacing=0 bgcolor='#ffffff'>"";
oDoc.write(strShow);
for(i=0; i<this.items.length; i++)
{
this.items[i].show(oDoc);
}
strShow = ""</table></td><td></td></tr>"";
strShow += ""<tr height='3'><td bgcolor='#d0d0ce'></td><td>"";
strShow += ""<table border='0' width='100%' height='100%' cellpadding=0 cellspacing=0 bgcolor='#ffffff'>"";
strShow += ""<tr><td bgcolor='#d0d0ce' width='23'></td><td><img src=' ' height='1' border='0'></td></tr></table>"";
strShow += ""</td><td></td></tr>"";
strShow += ""</table></div>\n"";
oDoc.write(strShow);
}
}
function contextItem(text, icon, cmd, url, target, type)
{
this.text = text ? text : '';
this.icon = icon ? icon : '';
this.cmd = cmd ? cmd : '';
this.url = url ? url : '';
this.target =target ? target : '';
this.type = type ? type : 'Link';
this.show = function (oDoc)
{
var strShow = '';
if(this.type == 'Link' || this.type == 'Command')
{
strShow += ""<tr "";
strShow += ""οnmοuseοver=\""changeStyle(this, 'on');\"" "";
strShow += ""οnmοuseοut=\""changeStyle(this, 'out');\"" "";
if (this.type == 'Command')
{
// 右键菜单是按钮类型,调用所对应的按钮的click事件
strShow += ""οnclick=\""document.getElementById("";
strShow += ""_rowClientId + "";
strShow += ""'_"";
strShow += this.cmd;
strShow += ""').click()"";
}
else
{
// 右键菜单是链接类型
if (this.target == 'Top') this.target = 'top';
if (this.target == 'Self') this.target = 'self';
if (this.target == 'top' || this.target == 'self')
{
strShow += ""οnclick=\"""";
strShow += this.target;
strShow += "".location='"";
strShow += this.url;
strShow += ""'"";
}
else
{
strShow += ""οnclick=\""window.open('"";
strShow += this.url;
strShow += ""')"";
}
}
strShow += ""\"">"";
strShow += ""<td class='ltdexit' width='16'>"";
if (this.icon == '')
{
strShow += ' ';
}
else
{
strShow += ""<img border='0' src='"";
strShow += this.icon;
strShow += ""' width='16' height='16' style='POSITION: relative'></img>"";
}
strShow += ""</td><td class='mtdexit'>"";
strShow += this.text;
strShow += ""</td><td class='rtdexit' width='5'> </td></tr>"";
}
// 右键菜单是分隔线
else if (this.type == 'Separator')
{
strShow += ""<tr><td class='ltdexit'> </td>"";
strShow += ""<td class='mtdexit' colspan='2'><hr color='#000000' size='1'></td></tr>"";
}
oDoc.write(strShow);
}
}
function changeStyle(obj, cmd)
{
if(obj)
{
try
{
var imgObj = obj.children(0).children(0);
if(cmd == 'on')
{
obj.children(0).className = 'ltdfocus';
obj.children(1).className = 'mtdfocus';
obj.children(2).className = 'rtdfocus';
if(imgObj)
{
if(imgObj.tagName.toUpperCase() == 'IMG')
{
imgObj.style.left = '-1px';
imgObj.style.top = '-1px';
}
}
}
else if(cmd == 'out')
{
obj.children(0).className = 'ltdexit';
obj.children(1).className = 'mtdexit';
obj.children(2).className = 'rtdexit';
if(imgObj)
{
if(imgObj.tagName.toUpperCase() == 'IMG')
{
imgObj.style.left = '0px';
imgObj.style.top = '0px';
}
}
}
}
catch (e) {}
}
}
function showMenu(rowClientId)
{
_rowClientId = rowClientId;
var x, y, w, h, ox, oy;
x = event.clientX;
y = event.clientY;
var obj = document.getElementById('rightmenu');
if (obj == null)
return true;
ox = document.body.clientWidth;
oy = document.body.clientHeight;
if(x > ox || y > oy)
return false;
w = obj.offsetWidth;
h = obj.offsetHeight;
if((x + w) > ox)
x = x - w;
if((y + h) > oy)
y = y - h;
// obj.style.posLeft = x + document.body.scrollLeft;
// obj.style.posTop = y + document.body.scrollTop;
// xhtml不支持上面的了
// 就是说如果你的页头声明了页是xhtml的话就不能用上面那句了,vs2005创建的aspx会默认加上xhtml声明
// 此时应该用如下的方法
obj.style.posLeft = x + document.documentElement.scrollLeft;
obj.style.posTop = y + document.documentElement.scrollTop;
obj.style.visibility = 'visible';
return false;
}
function hideMenu()
{
if(event.button == 0)
{
var obj = document.getElementById('rightmenu');
if (obj == null)
return true;
obj.style.visibility = 'hidden';
obj.style.posLeft = 0;
obj.style.posTop = 0;
}
}
function writeStyle()
{
var strStyle = '';
strStyle += ""<STYLE type='text/css'>"";
strStyle += ""TABLE {Font-FAMILY: 'Tahoma','Verdana','宋体'; FONT-SIZE: 9pt}"";
strStyle += "".mtdfocus {BACKGROUND-COLOR: #ccccff; BORDER-BOTTOM: #000000 1px solid; BORDER-TOP: #000000 1px solid; CURSOR: hand}"";
strStyle += "".mtdexit {BACKGROUND-COLOR: #ffffff; BORDER-BOTTOM: #ffffff 1px solid; BORDER-TOP: #ffffff 1px solid}"";
strStyle += "".ltdfocus {BACKGROUND-COLOR: #ccccff; BORDER-BOTTOM: #000000 1px solid; BORDER-TOP: #000000 1px solid; BORDER-LEFT: #000000 1px solid; CURSOR: hand}"";
strStyle += "".ltdexit {BACKGROUND-COLOR: #d0d0ce; BORDER-BOTTOM: #d0d0ce 1px solid; BORDER-TOP: #d0d0ce 1px solid; BORDER-LEFT: #d0d0ce 1px solid}"";
strStyle += "".rtdfocus {BACKGROUND-COLOR: #ccccff; BORDER-BOTTOM: #000000 1px solid; BORDER-TOP: #000000 1px solid; BORDER-RIGHT: #000000 1px solid; CURSOR: hand}"";
strStyle += "".rtdexit {BACKGROUND-COLOR: #ffffff; BORDER-BOTTOM: #ffffff 1px solid; BORDER-TOP: #ffffff 1px solid; BORDER-RIGHT: #ffffff 1px solid}"";
strStyle += ""</STYLE>"";
document.write(strStyle);
}
function makeMenu()
{
var myMenu, item;
myMenu = new contextMenu();
// 增加右键菜单项 开始
// item = new contextItem("", "", "", "", "", "");
// 1-菜单项的文本
// 2-图标链接
// 3-所调用的命令按钮的ID
// 4-链接地址
// 5-链接的target
// 6-右键菜单的项的类别
// myMenu.addItem(item);
[$MakeMenu$]
// 增加右键菜单项 结束
myMenu.show(this.document);
delete item;
delete myMenu;
}
function toggleMenu(isEnable)
{
if(isEnable)
document.oncontextmenu = showMenu;
else
document.oncontextmenu = new function() {return true;};
}
writeStyle();
makeMenu();
document.onclick = hideMenu;
//]]>
</script>";
}
}
6、重写OnPreRender方法,注册上面那段客户端脚本
/**/
/// <summary>
/// OnPreRender
/// </summary>
/// <param name="e"></param>
protected override void OnPreRender(EventArgs e)
{
if (ContextMenus.Count > 0)
{
StringBuilder sb = new StringBuilder();
foreach (ContextMenu cm in ContextMenus)
{
// item = new contextItem("", "", "", "", "", "");
// 1-菜单项的文本
// 2-图标链接
// 3-所调用的命令按钮的ID
// 4-链接地址
// 5-链接的target
// 6-右键菜单的项的类别
// 命令按钮
if (cm.ItemType == ContextMenu.ItemTypeCollection.Command)
{
sb.Append("item = new contextItem(\"" + cm.Text +
"\", \"" + ResolveUrl(cm.Icon) + "\", \"" +
cm.CommandButtonId + "\", \"\", \"\", \"Command\");");
}
// 链接
else if (cm.ItemType == ContextMenu.ItemTypeCollection.Link)
{
sb.Append("item = new contextItem(\"" + cm.Text +
"\", \"" + ResolveUrl(cm.Icon) + "\", \"\", \"" +
cm.NavigateUrl + "\", \"" +
cm.Target + "\", \"Link\");");
}
// 分隔线
else if (cm.ItemType == ContextMenu.ItemTypeCollection.Separator)
{
sb.Append("item = new contextItem(\"\", \"\", \"\", \"\", \"\", \"Separator\");");
}
sb.Append("myMenu.addItem(item);");
}
// 注册客户端代码
if (!Page.ClientScript.IsClientScriptBlockRegistered("jsContextMenu"))
{
Page.ClientScript.RegisterClientScriptBlock(
this.GetType(),
"jsContextMenu", JavaScriptConstant.jsContextMenu.Replace("[$MakeMenu$]", sb.ToString())
);
}
}
base.OnPreRender(e);
}
/// OnPreRender
/// </summary>
/// <param name="e"></param>
protected override void OnPreRender(EventArgs e)
{
if (ContextMenus.Count > 0)
{
StringBuilder sb = new StringBuilder();
foreach (ContextMenu cm in ContextMenus)
{
// item = new contextItem("", "", "", "", "", "");
// 1-菜单项的文本
// 2-图标链接
// 3-所调用的命令按钮的ID
// 4-链接地址
// 5-链接的target
// 6-右键菜单的项的类别
// 命令按钮
if (cm.ItemType == ContextMenu.ItemTypeCollection.Command)
{
sb.Append("item = new contextItem(\"" + cm.Text +
"\", \"" + ResolveUrl(cm.Icon) + "\", \"" +
cm.CommandButtonId + "\", \"\", \"\", \"Command\");");
}
// 链接
else if (cm.ItemType == ContextMenu.ItemTypeCollection.Link)
{
sb.Append("item = new contextItem(\"" + cm.Text +
"\", \"" + ResolveUrl(cm.Icon) + "\", \"\", \"" +
cm.NavigateUrl + "\", \"" +
cm.Target + "\", \"Link\");");
}
// 分隔线
else if (cm.ItemType == ContextMenu.ItemTypeCollection.Separator)
{
sb.Append("item = new contextItem(\"\", \"\", \"\", \"\", \"\", \"Separator\");");
}
sb.Append("myMenu.addItem(item);");
}
// 注册客户端代码
if (!Page.ClientScript.IsClientScriptBlockRegistered("jsContextMenu"))
{
Page.ClientScript.RegisterClientScriptBlock(
this.GetType(),
"jsContextMenu", JavaScriptConstant.jsContextMenu.Replace("[$MakeMenu$]", sb.ToString())
);
}
}
base.OnPreRender(e);
}
7、重写OnRowDataBound给数据行增加客户端代码以调用我们注册的那段javascript,从而实现给GridView的数据行增加右键菜单的功能。
/**/
/// <summary>
/// OnRowDataBound
/// </summary>
/// <param name="e"></param>
protected override void OnRowDataBound(GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// 给数据行增加客户端代码
e.Row.Attributes.Add("oncontextmenu", "showMenu('" + e.Row.ClientID + "');return false;");
}
base.OnRowDataBound(e);
}
/// OnRowDataBound
/// </summary>
/// <param name="e"></param>
protected override void OnRowDataBound(GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// 给数据行增加客户端代码
e.Row.Attributes.Add("oncontextmenu", "showMenu('" + e.Row.ClientID + "');return false;");
}
base.OnRowDataBound(e);
}
控件使用
添加这个控件到工具箱里,然后拖拽到webform上,设置如下属性:ItemType为右键菜单的项的类别(Link,Command,Separator);Icon为文字左边的图标的链接;Text为菜单的文字;CommandButtonId为所调用的命令按钮的ID;NavigateUrl为链接的url;Target为链接的target(Blank,Self,Top)
ObjData.cs
using
System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.ComponentModel;
/**/ /// <summary>
/// OjbData 的摘要说明
/// </summary>
public class OjbData
{
public OjbData()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
[DataObjectMethod(DataObjectMethodType.Select, true)]
public DataTable Select()
{
DataTable dt = new DataTable();
dt.Columns.Add("no", typeof(string));
dt.Columns.Add("name", typeof(string));
for (int i = 0; i < 30; i++)
{
DataRow dr = dt.NewRow();
dr[0] = "no" + i.ToString().PadLeft(2, '0');
dr[1] = "name" + i.ToString().PadLeft(2, '0');
dt.Rows.Add(dr);
}
return dt;
}
}
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.ComponentModel;
/**/ /// <summary>
/// OjbData 的摘要说明
/// </summary>
public class OjbData
{
public OjbData()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
[DataObjectMethod(DataObjectMethodType.Select, true)]
public DataTable Select()
{
DataTable dt = new DataTable();
dt.Columns.Add("no", typeof(string));
dt.Columns.Add("name", typeof(string));
for (int i = 0; i < 30; i++)
{
DataRow dr = dt.NewRow();
dr[0] = "no" + i.ToString().PadLeft(2, '0');
dr[1] = "name" + i.ToString().PadLeft(2, '0');
dt.Rows.Add(dr);
}
return dt;
}
}
Default.aspx
<%
@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default"
%>
<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
< html xmlns ="http://www.w3.org/1999/xhtml" >
< head runat ="server" >
< title > SmartGridView测试 </ title >
</ head >
< body >
< form id ="form1" runat ="server" >
< div >
< yyc:SmartGridView ID ="SmartGridView1" runat ="server" DataSourceID ="ObjectDataSource1"
AutoGenerateColumns ="false" >
< Columns >
< asp:BoundField DataField ="no" HeaderText ="序号" SortExpression ="no" ItemStyle-Width ="100px" />
< asp:BoundField DataField ="name" HeaderText ="名称" SortExpression ="name" ItemStyle-Width ="100px" />
< asp:BoundField DataField ="no" HeaderText ="序号" SortExpression ="no" ItemStyle-Width ="100px" />
< asp:BoundField DataField ="name" HeaderText ="名称" SortExpression ="name" ItemStyle-Width ="100px" />
< asp:BoundField DataField ="no" HeaderText ="序号" SortExpression ="no" ItemStyle-Width ="100px" />
< asp:BoundField DataField ="name" HeaderText ="名称" SortExpression ="name" ItemStyle-Width ="100px" />
< asp:TemplateField >
< footerstyle cssclass ="hidden" />
< headerstyle cssclass ="hidden" />
< itemstyle cssclass ="hidden" />
< itemtemplate >
< asp:Button id ="btnRightMenuButton" runat ="server" CommandName ="RightMenuButton" CommandArgument ='<%# Container.DataItemIndex % > ' />
</ itemtemplate >
</ asp:TemplateField >
</ Columns >
< ContextMenus >
< yyc:ContextMenu ItemType ="Command" Text ="右键菜单按钮测试" Icon ="~/Images/button.gif" CommandButtonId ="btnRightMenuButton" />
< yyc:ContextMenu ItemType ="Separator" />
< yyc:ContextMenu ItemType ="Link" Text ="控件源代码" Icon ="~/Images/button.gif" NavigateUrl ="http://webabcd.cnblogs.com"
Target ="Blank" />
</ ContextMenus >
</ yyc:SmartGridView >
< asp:ObjectDataSource ID ="ObjectDataSource1" runat ="server" SelectMethod ="Select"
TypeName ="OjbData" ></ asp:ObjectDataSource >
</ div >
</ form >
</ body >
</ html >
<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
< html xmlns ="http://www.w3.org/1999/xhtml" >
< head runat ="server" >
< title > SmartGridView测试 </ title >
</ head >
< body >
< form id ="form1" runat ="server" >
< div >
< yyc:SmartGridView ID ="SmartGridView1" runat ="server" DataSourceID ="ObjectDataSource1"
AutoGenerateColumns ="false" >
< Columns >
< asp:BoundField DataField ="no" HeaderText ="序号" SortExpression ="no" ItemStyle-Width ="100px" />
< asp:BoundField DataField ="name" HeaderText ="名称" SortExpression ="name" ItemStyle-Width ="100px" />
< asp:BoundField DataField ="no" HeaderText ="序号" SortExpression ="no" ItemStyle-Width ="100px" />
< asp:BoundField DataField ="name" HeaderText ="名称" SortExpression ="name" ItemStyle-Width ="100px" />
< asp:BoundField DataField ="no" HeaderText ="序号" SortExpression ="no" ItemStyle-Width ="100px" />
< asp:BoundField DataField ="name" HeaderText ="名称" SortExpression ="name" ItemStyle-Width ="100px" />
< asp:TemplateField >
< footerstyle cssclass ="hidden" />
< headerstyle cssclass ="hidden" />
< itemstyle cssclass ="hidden" />
< itemtemplate >
< asp:Button id ="btnRightMenuButton" runat ="server" CommandName ="RightMenuButton" CommandArgument ='<%# Container.DataItemIndex % > ' />
</ itemtemplate >
</ asp:TemplateField >
</ Columns >
< ContextMenus >
< yyc:ContextMenu ItemType ="Command" Text ="右键菜单按钮测试" Icon ="~/Images/button.gif" CommandButtonId ="btnRightMenuButton" />
< yyc:ContextMenu ItemType ="Separator" />
< yyc:ContextMenu ItemType ="Link" Text ="控件源代码" Icon ="~/Images/button.gif" NavigateUrl ="http://webabcd.cnblogs.com"
Target ="Blank" />
</ ContextMenus >
</ yyc:SmartGridView >
< asp:ObjectDataSource ID ="ObjectDataSource1" runat ="server" SelectMethod ="Select"
TypeName ="OjbData" ></ asp:ObjectDataSource >
</ div >
</ form >
</ body >
</ html >
注:如果想修改右键菜单的样式,请自行修改javascript,我就不把他们弄出来了。
OK
转载于:https://blog.51cto.com/dotnet/54546