GridView既强大又好用。为了让它更强大、更好用,我们来写一个继承自GridView的控件。
[索引页]
[×××]
作者: webabcd
[索引页]
[×××]
扩展GridView控件(9) - 给数据行增加右键菜单
作者: webabcd
/*正式版的实现 开始*/
介绍
扩展GridView控件:
给数据行增加右键菜单,响应服务端事件或超级链接
使用方法(设置ContextMenus集合属性):
Text - 菜单的文本内容
BoundCommandName - 需要绑定的CommandName
NavigateUrl - 链接的URL
Target - 链接的目标窗口或框架
SmartGridView的属性ContextMenuCssClass - 右键菜单的级联样式表 CSS 类名(右键菜单的结构div ul li a)
关键代码
js
扩展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. = 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(' 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. = 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(' 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.οncοntextmenu=function(evt){return yy_sgv_rightMenu.show(evt);};";
scriptString += "document.οnclick=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.οncοntextmenu=function(evt){return yy_sgv_rightMenu.show(evt);};";
scriptString += "document.οnclick=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的类。
给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
{
}
转载于:https://blog.51cto.com/webabcd/345561