扩展GridView控件(9) - 给数据行增加右键菜单

[源码下载] 

扩展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);
}
/**//*右键菜单 结束*/
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; }
/**//*右键菜单的示例样式 结束*/

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);
            }
        }

    }
}

/*正式版的实现 结束*/

/*测试版的实现 开始*/
介绍
给GridView的数据行增加右键菜单可以增加用户体验,不过实现起来挺麻烦的,现在我们扩展一下GridView控件以实现这样的功能。


控件开发
1、新建一个继承自GridView的类。
/** <summary>
/// 继承自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
        }
    }
}

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";
        }
    }
}

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;
            }
        }
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 += '&nbsp;';
                    }
                    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'>&nbsp;</td></tr>"";
                }
                // 右键菜单是分隔线
                else if (this.type == 'Separator')
                {
                    strShow += ""<tr><td class='ltdexit'>&nbsp;</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);
        }

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);
        }


控件使用
添加这个控件到工具箱里,然后拖拽到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;
    }
}

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>

注:如果想修改右键菜单的样式,请自行修改javascript,我就不把他们弄出来了。

/*测试版的实现 结束*/ 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值