扩展GridView控件(9) - 给数据行增加右键菜单
GridView既强大又好用。为了让它更强大、更好用,我们来写一个继承自GridView的控件。
[索引页]
[源码下载]
作者:webabcd
介绍
扩展GridView控件:
给数据行增加右键菜单,响应服务端事件或超级链接
使用方法(设置ContextMenus集合属性):
Text - 菜单的文本内容
BoundCommandName - 需要绑定的CommandName
NavigateUrl - 链接的URL
Target - 链接的目标窗口或框架
SmartGridView的属性ContextMenuCssClass - 右键菜单的级联样式表 CSS 类名(右键菜单的结构div ul li a)
关键代码
js
css
c#
介绍
给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,我就不把他们弄出来了。
OK
[源码下载]
[索引页]
[源码下载]
扩展GridView控件(9) - 给数据行增加右键菜单
作者:webabcd
/*正式版的实现 开始*/
介绍
扩展GridView控件:
给数据行增加右键菜单,响应服务端事件或超级链接
使用方法(设置ContextMenus集合属性):
Text - 菜单的文本内容
BoundCommandName - 需要绑定的CommandName
NavigateUrl - 链接的URL
Target - 链接的目标窗口或框架
SmartGridView的属性ContextMenuCssClass - 右键菜单的级联样式表 CSS 类名(右键菜单的结构div ul li a)
关键代码
js
/*右键菜单 开始*/
yy_sgv_rightMenu = function ()
{
/// <summary>构造函数</summary>
this._menu = null;
this._menuItem = null;
this._handle = null;
this._target = null;
this._cssClass = null
};
yy_sgv_rightMenu.prototype =
{
/// <summary>相关属性和相关方法</summary>
get_menu: function()
{
return this._menu;
},
set_menu: function(value)
{
this._menu = value;
},
get_handle: function()
{
return this._handle;
},
set_handle: function(value)
{
this._handle = value;
},
get_target: function()
{
return this._target;
},
set_target: function(value)
{
this._target = value;
},
get_cssClass: function()
{
return this._cssClass;
},
set_cssClass: function(value)
{
this._cssClass = value;
},
get_menuItem: function()
{
return this._menuItem;
},
set_menuItem: function(value)
{
this._menuItem = value;
},
show:function(e)
{
if (this.get_menuItem() == null)
{
this.hidden();
return true;
}
var rightMenu = this.get_menu();
if (rightMenu == null)
{
rightMenu = document.createElement("div");
}
var menuInnerHTML = ""; // 菜单容器里的HTML内容
var $items = this.get_menuItem();
var $handle = this.get_handle();
var $target = this.get_target();
rightMenu.className = "yy_sgv_rightMenuBase";
if (this.get_cssClass() == null || this.get_cssClass() == "")
rightMenu.className += " " + "yy_sgv_rightMenu";
else
rightMenu.className += " " + this.get_cssClass();
menuInnerHTML += "<ul>";
for (var i in $items)
{
if ($items[i].indexOf("<hr") != -1)
{
menuInnerHTML += $items[i];
}
else
{
if ($target[i] == "")
{
$target[i] = "_self";
}
menuInnerHTML += "<li><a href=\"" + $handle[i] + "\" target=\"" + $target[i] + "\">";
menuInnerHTML += $items[i];
menuInnerHTML += "</a></li>";
}
}
menuInnerHTML += "</ul>";
// alert(menuInnerHTML);
rightMenu.innerHTML = menuInnerHTML;
rightMenu.style.visibility = "visible";
rightMenu.onmousedown = function(e)
{
e=e||window.event;
document.all ? e.cancelBubble = true : e.stopPropagation();
}
rightMenu.onselectstart = function()
{
return false;
}
document.body.appendChild(rightMenu);
this.set_menu(rightMenu); // 方便别的方法引用
e = e || window.event;
var root = document.documentElement;
var x = root.scrollLeft + e.clientX;
var y = root.scrollTop + e.clientY;
if (this.get_menu().clientWidth+e.clientX > root.clientWidth)
{
x = x - this.get_menu().clientWidth;
}
if (this.get_menu().clientHeight+e.clientY > root.clientHeight)
{
y = y - this.get_menu().clientHeight;
}
this.get_menu().style.left = x + "px";
this.get_menu().style.top = y + "px";
this.get_menu().style.visibility = "visible";
this.set_handle(null);
this.set_menuItem(null);
this.set_target(null);
return false;
},
hidden:function()
{
if (this.get_menu() != null)
{
this.get_menu().style.visibility = "hidden";
}
}
}
if (document.all)
{
window.attachEvent('onload', yy_sgv_rightMenu = new yy_sgv_rightMenu())
}
else
{
window.addEventListener('load', yy_sgv_rightMenu = new yy_sgv_rightMenu(), false);
}
function yy_sgv_setRightMenu(handle, menuItem, target, cssClass)
{
/// <summary>设置需要显示的右键菜单</summary>
yy_sgv_rightMenu.set_handle(handle);
yy_sgv_rightMenu.set_menuItem(menuItem);
yy_sgv_rightMenu.set_target(target);
yy_sgv_rightMenu.set_cssClass(cssClass);
}
/*右键菜单 结束*/
yy_sgv_rightMenu = function ()
{
/// <summary>构造函数</summary>
this._menu = null;
this._menuItem = null;
this._handle = null;
this._target = null;
this._cssClass = null
};
yy_sgv_rightMenu.prototype =
{
/// <summary>相关属性和相关方法</summary>
get_menu: function()
{
return this._menu;
},
set_menu: function(value)
{
this._menu = value;
},
get_handle: function()
{
return this._handle;
},
set_handle: function(value)
{
this._handle = value;
},
get_target: function()
{
return this._target;
},
set_target: function(value)
{
this._target = value;
},
get_cssClass: function()
{
return this._cssClass;
},
set_cssClass: function(value)
{
this._cssClass = value;
},
get_menuItem: function()
{
return this._menuItem;
},
set_menuItem: function(value)
{
this._menuItem = value;
},
show:function(e)
{
if (this.get_menuItem() == null)
{
this.hidden();
return true;
}
var rightMenu = this.get_menu();
if (rightMenu == null)
{
rightMenu = document.createElement("div");
}
var menuInnerHTML = ""; // 菜单容器里的HTML内容
var $items = this.get_menuItem();
var $handle = this.get_handle();
var $target = this.get_target();
rightMenu.className = "yy_sgv_rightMenuBase";
if (this.get_cssClass() == null || this.get_cssClass() == "")
rightMenu.className += " " + "yy_sgv_rightMenu";
else
rightMenu.className += " " + this.get_cssClass();
menuInnerHTML += "<ul>";
for (var i in $items)
{
if ($items[i].indexOf("<hr") != -1)
{
menuInnerHTML += $items[i];
}
else
{
if ($target[i] == "")
{
$target[i] = "_self";
}
menuInnerHTML += "<li><a href=\"" + $handle[i] + "\" target=\"" + $target[i] + "\">";
menuInnerHTML += $items[i];
menuInnerHTML += "</a></li>";
}
}
menuInnerHTML += "</ul>";
// alert(menuInnerHTML);
rightMenu.innerHTML = menuInnerHTML;
rightMenu.style.visibility = "visible";
rightMenu.onmousedown = function(e)
{
e=e||window.event;
document.all ? e.cancelBubble = true : e.stopPropagation();
}
rightMenu.onselectstart = function()
{
return false;
}
document.body.appendChild(rightMenu);
this.set_menu(rightMenu); // 方便别的方法引用
e = e || window.event;
var root = document.documentElement;
var x = root.scrollLeft + e.clientX;
var y = root.scrollTop + e.clientY;
if (this.get_menu().clientWidth+e.clientX > root.clientWidth)
{
x = x - this.get_menu().clientWidth;
}
if (this.get_menu().clientHeight+e.clientY > root.clientHeight)
{
y = y - this.get_menu().clientHeight;
}
this.get_menu().style.left = x + "px";
this.get_menu().style.top = y + "px";
this.get_menu().style.visibility = "visible";
this.set_handle(null);
this.set_menuItem(null);
this.set_target(null);
return false;
},
hidden:function()
{
if (this.get_menu() != null)
{
this.get_menu().style.visibility = "hidden";
}
}
}
if (document.all)
{
window.attachEvent('onload', yy_sgv_rightMenu = new yy_sgv_rightMenu())
}
else
{
window.addEventListener('load', yy_sgv_rightMenu = new yy_sgv_rightMenu(), false);
}
function yy_sgv_setRightMenu(handle, menuItem, target, cssClass)
{
/// <summary>设置需要显示的右键菜单</summary>
yy_sgv_rightMenu.set_handle(handle);
yy_sgv_rightMenu.set_menuItem(menuItem);
yy_sgv_rightMenu.set_target(target);
yy_sgv_rightMenu.set_cssClass(cssClass);
}
/*右键菜单 结束*/
css
/*右键菜单必须要具有的样式*/
.yy_sgv_rightMenuBase
{
visibility: hidden;
position: absolute;
}
/*右键菜单的示例样式 开始*/
.yy_sgv_rightMenu
{
border-right: 2px outset;
border-top: 2px outset;
border-left: 2px outset;
border-bottom: 2px outset;
background-color: buttonface;
}
.yy_sgv_rightMenu hr
{
width: 300px;
}
.yy_sgv_rightMenu ul
{
list-style: none; margin:0; padding:0;
}
.yy_sgv_rightMenu ul li
{
vertical-align: bottom;
}
.yy_sgv_rightMenu A { color: MenuText; text-decoration: none; display: block; width: 300px; text-align:center; line-height:20px }
.yy_sgv_rightMenu A:link { color: MenuText; text-decoration: none; }
.yy_sgv_rightMenu A:active { color: MenuText; text-decoration: none; }
.yy_sgv_rightMenu A:visited { color: MenuText; text-decoration: none; }
.yy_sgv_rightMenu A:hover { color: HighlightText; background-color: Highlight; }
/*右键菜单的示例样式 结束*/
.yy_sgv_rightMenuBase
{
visibility: hidden;
position: absolute;
}
/*右键菜单的示例样式 开始*/
.yy_sgv_rightMenu
{
border-right: 2px outset;
border-top: 2px outset;
border-left: 2px outset;
border-bottom: 2px outset;
background-color: buttonface;
}
.yy_sgv_rightMenu hr
{
width: 300px;
}
.yy_sgv_rightMenu ul
{
list-style: none; margin:0; padding:0;
}
.yy_sgv_rightMenu ul li
{
vertical-align: bottom;
}
.yy_sgv_rightMenu A { color: MenuText; text-decoration: none; display: block; width: 300px; text-align:center; line-height:20px }
.yy_sgv_rightMenu A:link { color: MenuText; text-decoration: none; }
.yy_sgv_rightMenu A:active { color: MenuText; text-decoration: none; }
.yy_sgv_rightMenu A:visited { color: MenuText; text-decoration: none; }
.yy_sgv_rightMenu A:hover { color: HighlightText; background-color: Highlight; }
/*右键菜单的示例样式 结束*/
c#
using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI.WebControls;
using System.Web.UI;
namespace YYControls.SmartGridViewFunction
{
/// <summary>
/// 扩展功能:给数据行增加右键菜单
/// </summary>
public class ContextMenuFunction : ExtendFunction
{
List<string> _rowRightClickButtonUniqueIdList = new List<string>();
private string _menuItem;
private string _target;
/// <summary>
/// 构造函数
/// </summary>
public ContextMenuFunction()
: base()
{
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="sgv">SmartGridView对象</param>
public ContextMenuFunction(SmartGridView sgv)
: base(sgv)
{
}
/// <summary>
/// 扩展功能的实现
/// </summary>
protected override void Execute()
{
this._sgv.RowDataBoundDataRow += new SmartGridView.RowDataBoundDataRowHandler(_sgv_RowDataBoundDataRow);
this._sgv.PreRender += new EventHandler(_sgv_PreRender);
this._sgv.RenderBegin += new SmartGridView.RenderBeginHandler(_sgv_RenderBegin);
foreach (ContextMenu cm in this._sgv.ContextMenus)
{
string text = cm.Text == null ? "" : cm.Text;
string target = cm.Target == null ? "" : cm.Target;
this._menuItem += String.Format(",\"{0}\"", text.Replace(",", ","));
this._target += String.Format(",\"{0}\"", target.Replace(",", ","));
}
this._menuItem = String.Format("new Array({0})", this._menuItem.TrimStart(','));
this._target = String.Format("new Array({0})", this._target.TrimStart(','));
}
void _sgv_RowDataBoundDataRow(object sender, GridViewRowEventArgs e)
{
string handle = "";
// 从用户定义的ContextMenus集合中分解出ContextMenu
foreach (ContextMenu cm in this._sgv.ContextMenus)
{
if (!String.IsNullOrEmpty(cm.NavigateUrl))
{
handle += String.Format(",\"{0}\"", cm.NavigateUrl);
continue;
}
else if (String.IsNullOrEmpty(cm.BoundCommandName))
{
handle += String.Format(",\"{0}\"", "#");
continue;
}
foreach (TableCell tc in e.Row.Cells)
{
bool bln = false;
foreach (Control c in tc.Controls)
{
// 如果控件继承自接口IButtonControl
if (c is IButtonControl
&& ((IButtonControl)c).CommandName == cm.BoundCommandName)
{
handle += String.Format(",\"{0}\"", this._sgv.Page.ClientScript.GetPostBackClientHyperlink(c, ""));
_rowRightClickButtonUniqueIdList.Add(c.UniqueID);
bln = true;
break;
}
}
if (bln)
{
break;
}
}
}
handle = String.Format("new Array({0})", handle.TrimStart(','));
string oncontextmenuValue =
String.Format
(
"yy_sgv_setRightMenu({0},{1}_rightMenuItem,{1}_rightMenuTarget, {2})",
handle,
this._sgv.ClientID,
String.IsNullOrEmpty(this._sgv.ContextMenuCssClass) ? "null" : "'" + this._sgv.ContextMenuCssClass + "'"
);
// 设置按钮的客户端属性
YYControls.Helper.Common.SetAttribute(
e.Row,
"oncontextmenu",
oncontextmenuValue,
AttributeValuePosition.Last);
}
/// <summary>
/// SmartGridView的PreRender事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void _sgv_PreRender(object sender, EventArgs e)
{
// 构造所需脚本
string scriptString = "";
scriptString += "document.oncontextmenu=function(evt){return yy_sgv_rightMenu.show(evt);};";
scriptString += "document.onclick=function(){yy_sgv_rightMenu.hidden();};";
// 注册所需脚本
if (!this._sgv.Page.ClientScript.IsClientScriptBlockRegistered("yy_sgv_rightMenu"))
{
this._sgv.Page.ClientScript.RegisterClientScriptBlock
(
this._sgv.GetType(),
"yy_sgv_rightMenu",
scriptString,
true
);
}
// 为每个SmartGridView注册与右键菜单相关的变量
if (!this._sgv.Page.ClientScript.IsClientScriptBlockRegistered(String.Format("yy_sgv_rightMenu_{0}", this._sgv.ClientID)))
{
this._sgv.Page.ClientScript.RegisterClientScriptBlock
(
this._sgv.GetType(),
String.Format("yy_sgv_rightMenu_{0}", this._sgv.ClientID),
String.Format(
"var {0}_rightMenuItem={1};var {0}_rightMenuTarget={2};",
this._sgv.ClientID,
this._menuItem,
this._target),
true
);
}
}
/// <summary>
/// RenderBegin
/// </summary>
/// <param name="sender"></param>
/// <param name="writer"></param>
void _sgv_RenderBegin(object sender, HtmlTextWriter writer)
{
foreach (string uniqueId in this._rowRightClickButtonUniqueIdList)
{
// 注册回发或回调数据以进行验证
this._sgv.Page.ClientScript.RegisterForEventValidation(uniqueId);
}
}
}
}
using System.Collections.Generic;
using System.Text;
using System.Web.UI.WebControls;
using System.Web.UI;
namespace YYControls.SmartGridViewFunction
{
/// <summary>
/// 扩展功能:给数据行增加右键菜单
/// </summary>
public class ContextMenuFunction : ExtendFunction
{
List<string> _rowRightClickButtonUniqueIdList = new List<string>();
private string _menuItem;
private string _target;
/// <summary>
/// 构造函数
/// </summary>
public ContextMenuFunction()
: base()
{
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="sgv">SmartGridView对象</param>
public ContextMenuFunction(SmartGridView sgv)
: base(sgv)
{
}
/// <summary>
/// 扩展功能的实现
/// </summary>
protected override void Execute()
{
this._sgv.RowDataBoundDataRow += new SmartGridView.RowDataBoundDataRowHandler(_sgv_RowDataBoundDataRow);
this._sgv.PreRender += new EventHandler(_sgv_PreRender);
this._sgv.RenderBegin += new SmartGridView.RenderBeginHandler(_sgv_RenderBegin);
foreach (ContextMenu cm in this._sgv.ContextMenus)
{
string text = cm.Text == null ? "" : cm.Text;
string target = cm.Target == null ? "" : cm.Target;
this._menuItem += String.Format(",\"{0}\"", text.Replace(",", ","));
this._target += String.Format(",\"{0}\"", target.Replace(",", ","));
}
this._menuItem = String.Format("new Array({0})", this._menuItem.TrimStart(','));
this._target = String.Format("new Array({0})", this._target.TrimStart(','));
}
void _sgv_RowDataBoundDataRow(object sender, GridViewRowEventArgs e)
{
string handle = "";
// 从用户定义的ContextMenus集合中分解出ContextMenu
foreach (ContextMenu cm in this._sgv.ContextMenus)
{
if (!String.IsNullOrEmpty(cm.NavigateUrl))
{
handle += String.Format(",\"{0}\"", cm.NavigateUrl);
continue;
}
else if (String.IsNullOrEmpty(cm.BoundCommandName))
{
handle += String.Format(",\"{0}\"", "#");
continue;
}
foreach (TableCell tc in e.Row.Cells)
{
bool bln = false;
foreach (Control c in tc.Controls)
{
// 如果控件继承自接口IButtonControl
if (c is IButtonControl
&& ((IButtonControl)c).CommandName == cm.BoundCommandName)
{
handle += String.Format(",\"{0}\"", this._sgv.Page.ClientScript.GetPostBackClientHyperlink(c, ""));
_rowRightClickButtonUniqueIdList.Add(c.UniqueID);
bln = true;
break;
}
}
if (bln)
{
break;
}
}
}
handle = String.Format("new Array({0})", handle.TrimStart(','));
string oncontextmenuValue =
String.Format
(
"yy_sgv_setRightMenu({0},{1}_rightMenuItem,{1}_rightMenuTarget, {2})",
handle,
this._sgv.ClientID,
String.IsNullOrEmpty(this._sgv.ContextMenuCssClass) ? "null" : "'" + this._sgv.ContextMenuCssClass + "'"
);
// 设置按钮的客户端属性
YYControls.Helper.Common.SetAttribute(
e.Row,
"oncontextmenu",
oncontextmenuValue,
AttributeValuePosition.Last);
}
/// <summary>
/// SmartGridView的PreRender事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void _sgv_PreRender(object sender, EventArgs e)
{
// 构造所需脚本
string scriptString = "";
scriptString += "document.oncontextmenu=function(evt){return yy_sgv_rightMenu.show(evt);};";
scriptString += "document.onclick=function(){yy_sgv_rightMenu.hidden();};";
// 注册所需脚本
if (!this._sgv.Page.ClientScript.IsClientScriptBlockRegistered("yy_sgv_rightMenu"))
{
this._sgv.Page.ClientScript.RegisterClientScriptBlock
(
this._sgv.GetType(),
"yy_sgv_rightMenu",
scriptString,
true
);
}
// 为每个SmartGridView注册与右键菜单相关的变量
if (!this._sgv.Page.ClientScript.IsClientScriptBlockRegistered(String.Format("yy_sgv_rightMenu_{0}", this._sgv.ClientID)))
{
this._sgv.Page.ClientScript.RegisterClientScriptBlock
(
this._sgv.GetType(),
String.Format("yy_sgv_rightMenu_{0}", this._sgv.ClientID),
String.Format(
"var {0}_rightMenuItem={1};var {0}_rightMenuTarget={2};",
this._sgv.ClientID,
this._menuItem,
this._target),
true
);
}
}
/// <summary>
/// RenderBegin
/// </summary>
/// <param name="sender"></param>
/// <param name="writer"></param>
void _sgv_RenderBegin(object sender, HtmlTextWriter writer)
{
foreach (string uniqueId in this._rowRightClickButtonUniqueIdList)
{
// 注册回发或回调数据以进行验证
this._sgv.Page.ClientScript.RegisterForEventValidation(uniqueId);
}
}
}
}
/*正式版的实现 结束*/
/*测试版的实现 开始*/
介绍
给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 += ""onmouseover=\""changeStyle(this, 'on');\"" "";
strShow += ""onmouseout=\""changeStyle(this, 'out');\"" "";
if (this.type == 'Command')
{
// 右键菜单是按钮类型,调用所对应的按钮的click事件
strShow += ""onclick=\""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 += ""onclick=\"""";
strShow += this.target;
strShow += "".location='"";
strShow += this.url;
strShow += ""'"";
}
else
{
strShow += ""onclick=\""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 += ""onmouseover=\""changeStyle(this, 'on');\"" "";
strShow += ""onmouseout=\""changeStyle(this, 'out');\"" "";
if (this.type == 'Command')
{
// 右键菜单是按钮类型,调用所对应的按钮的click事件
strShow += ""onclick=\""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 += ""onclick=\"""";
strShow += this.target;
strShow += "".location='"";
strShow += this.url;
strShow += ""'"";
}
else
{
strShow += ""onclick=\""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)
{
if (ContextMenus.Count > 0)
{
// 给数据行增加客户端代码
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)
{
if (ContextMenus.Count > 0)
{
// 给数据行增加客户端代码
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
[源码下载]