webabcd - 专注于asp.net

ASP.NET
从现在开始 一切都不晚
posts - 149, comments - 4090, trackbacks - 328, articles - 0
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理
GridView既强大又好用。为了让它更强大、更好用,我们来写一个继承自GridView的控件。
[索引页]
[源码下载]


扩展GridView控件(1) - 鼠标经过行时改变行的样式


作者:webabcd


/*正式版的实现 开始*/

介绍
扩展GridView控件:
鼠标经过行的时候改变该行的样式,鼠标离开行的时候恢复该行的样式

使用方法(设置属性):
MouseOverCssClass - 鼠标经过行时行的 CSS 类名


关键代码
/*鼠标经过行时改变行的样式 开始*/
var yy_sgv_originalCssClassName = ''; // 初始样式

function yy_sgv_changeMouseOverCssClass(obj, cssClassName)
{
/// <summary>鼠标经过时改变样式</summary>

    
if (arguments.length == 1)
    
{
        yy_sgv_changeCssClass(obj, yy_sgv_originalCssClassName);
        yy_sgv_originalCssClassName 
= '';
    }

    
else
    
{
        yy_sgv_originalCssClassName 
= obj.className;
        yy_sgv_changeCssClass(obj, cssClassName);
    }

}

/*鼠标经过行时改变行的样式 结束*/

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


/*测试版的实现 开始*/

介绍
我们一般是通过在RowDataBound事件里编码的方式实现GridView的鼠标经过行时改变行的样式的功能。但是每次都这样做比较麻烦。所以我们来开发一个继承自GridView的控件,以扩展它的功能。通过设置其CssClassMouseOver属性来实现这样的功能。


控件开发
1、新建一个继承自GridView的类。
/// <summary>
/// 继承自GridView
/// </summary>

[ToolboxData(@"<{0}:SmartGridView runat='server'></{0}:SmartGridView>")]
public class SmartGridView : GridView
{
}

2、加一个属性,用来指定鼠标经过行时,行的css类名
        private string _cssClassMouseOver;
        
/// <summary>
        
/// 鼠标经过的样式 CSS 类名
        
/// </summary>

        [Browsable(true)]
        [Description(
"鼠标经过的样式 CSS 类名")]
        [DefaultValue(
"")]
        [Category(
"扩展")]
        
public virtual string CssClassMouseOver
        
{
            
get return _cssClassMouseOver; }
            
set { _cssClassMouseOver = value; }
        }


3、重写OnRowDataBound实现鼠标经过行时改变行的样式的功能。主要是给<tr>增加onmouseover事件和onmouseout事件。
        /// <summary>
        
/// OnRowDataBound
        
/// </summary>
        
/// <param name="e"></param>

        protected override void OnRowDataBound(GridViewRowEventArgs e)
        
{
            
if (e.Row.RowType == DataControlRowType.DataRow)
            
{
                
// _cssClassMouseOver不是空则执行
                if (!string.IsNullOrEmpty(this._cssClassMouseOver))
                
{
                    
// 在<tr>上onmouseover时<tr>的样式(css类名)
                    e.Row.Attributes.Add("onmouseover""this.className = '" + this._cssClassMouseOver + "'");

                    
// 样式的名称(css类名)
                    string cssClassMouseOut = "";

                    
// 根据RowState的不同,onmouseout时<tr>的不同样式(css类名)
                    switch (e.Row.RowState)
                    
{
                        
case DataControlRowState.Alternate:
                            cssClassMouseOut 
= base.AlternatingRowStyle.CssClass;
                            
break;
                        
case DataControlRowState.Edit:
                            cssClassMouseOut 
= base.EditRowStyle.CssClass;
                            
break;
                        
case DataControlRowState.Normal:
                            cssClassMouseOut 
= base.RowStyle.CssClass;
                            
break;
                        
case DataControlRowState.Selected:
                            cssClassMouseOut 
= base.SelectedRowStyle.CssClass;
                            
break;
                        
default:
                            cssClassMouseOut 
= "";
                            
break;
                    }


                    
// 增加<tr>的dhtml事件onmouseout
                    e.Row.Attributes.Add("onmouseout""this.className = '" + cssClassMouseOut + "'");
                }

            }


            
base.OnRowDataBound(e);
        }



控件使用
添加这个控件到工具箱里,然后拖拽到webform上,设置其CssClassMouseOver属性即可

aspx文件
<yyc:SmartGridView ID="sgvList" runat="server">
</yyc:SmartGridView>

css文件
.over 
{
    background-color 
: Red;
}


skin文件
<yyc:SmartGridView runat="server" CssClassMouseOver="over">
</yyc:SmartGridView>


注:其实最好的实现办法应该如下,但是因为之后我针对GridView扩展的其他功能可能会与此有冲突,所以没这么用。
        /// <summary>
        
/// 构造函数
        
/// </summary>

        public SmartGridView()
        
{
            
this.PreRender += new EventHandler(SmartGridView_PreRender);
        }


        
/// <summary>
        
/// PreRender
        
/// </summary>
        
/// <param name="sender">sender</param>
        
/// <param name="e">e</param>

        void SmartGridView_PreRender(object sender, EventArgs e)
        
{
            
if (!string.IsNullOrEmpty(this._cssClassMouseOver))
            
{
                
// 注册一个客户端变量
                if (!Page.ClientScript.IsClientScriptBlockRegistered("jsRowClass"))
                
{
                    Page.ClientScript.RegisterClientScriptBlock(
                        
this.GetType(),
                        
"jsRowClass",
                        
@"<script type=""text/javascript"">var yy_RowClass</script>"
                        );
                }

            }

        }


        
/// <summary>
        
/// OnRowDataBound
        
/// </summary>
        
/// <param name="e"></param>

        protected override void OnRowDataBound(GridViewRowEventArgs e)
        
{

            
if (e.Row.RowType == DataControlRowType.DataRow)
            
{
                
// _cssClassMouseOver不是空则执行
                if (!string.IsNullOrEmpty(this._cssClassMouseOver))
                
{
                    e.Row.Attributes.Add(
"onmouseover""yy_RowClass=this.className;this.className='" + _cssClassMouseOver + "'");
                    e.Row.Attributes.Add(
"onmouseout""this.className=yy_RowClass");
                }

            }


            
base.OnRowDataBound(e);
        }

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


OK
[源码下载]

Feedback

#1楼    回复  引用    

2007-02-05 22:39 by LiuJian [未注册用户]
谢谢作者共享自己的知识!!!!

#2楼 [楼主]   回复  引用  查看    

2007-02-05 22:55 by webabcd      
@LiuJian
:)
不谢,大家共同提高

#3楼    回复  引用    

2007-03-06 15:05 by lw [未注册用户]
你好。你码好象有点问题

#4楼 [楼主]   回复  引用  查看    

2007-03-06 23:09 by webabcd      
@lw
如果有bug,麻烦兄弟贴出来,我会马上修改的

#5楼    回复  引用    

2007-03-23 17:54 by 吴泽世 [未注册用户]
如果不使用Datasource控件好象效果出不来,呵呵

#6楼 [楼主]   回复  引用  查看    

2007-03-23 22:31 by webabcd      
@吴泽世
是地,有一些功能是要依靠数据源控件的

#7楼    回复  引用    

2007-03-25 19:18 by lfw [未注册用户]
这种样式的应用替代方式有多种,也可以用css样式表来实现。
如:td:hover{样式表}

#8楼 [楼主]   回复  引用  查看    

2007-03-26 08:26 by webabcd      
@lfw
按你的方法试了一遍,可惜没有成功

#9楼    回复  引用    

2007-03-26 09:31 by 无名人 [未注册用户]
值得参考,但不值得学习

#10楼 [楼主]   回复  引用  查看    

2007-03-26 10:13 by webabcd      
@无名人
:)
能有点用就好

#11楼    回复  引用    

2007-03-26 11:50 by stlh [未注册用户]
td:hover目前的浏览器好像不支持
a:hover才可以

#12楼 [楼主]   回复  引用  查看    

2007-03-26 12:30 by webabcd      
@stlh
嗯,测试的结果证明IE6是不支持td:hover的

#13楼    回复  引用    

2007-04-19 10:14 by 刘欢 [未注册用户]
报错:
说OnRowDataBound没有找到合适的方法来重写。。。

怎么解决啊?

#14楼 [楼主]   回复  引用  查看    

2007-04-19 10:35 by webabcd      
@刘欢
继承GridView了没
兄弟可以下一下源码看看

#15楼    回复  引用    

2007-04-19 10:46 by 刘欢 [未注册用户]
继承了

我只试了一下
扩展GridView控件(一)——鼠标经过行时改变行的样式 这部分。

代码是这部公的源码。

#16楼    回复  引用    

2007-04-19 10:49 by 刘欢 [未注册用户]
不好意思,是我弄错了,

刚刚开始学。见笑了。~~~

#17楼 [楼主]   回复  引用  查看    

2007-04-19 11:35 by webabcd      
@刘欢
:)
大家都是这么过来的

#18楼    回复  引用    

2007-05-05 18:52 by ayongwust [未注册用户]
感激!!!

#19楼 [楼主]   回复  引用  查看    

2007-05-05 21:14 by webabcd      
@ayongwust
:)

#20楼    回复  引用    

2007-05-06 10:30 by ayongwust [未注册用户]
@webabcd.

<ConfirmButtons>
<CheckboxAlls>
.
.
是<SmartGridView>的自定义标签吧,我想问的是满足什么条件才能成为控件的自定义的标签呢。

先谢谢了。

#21楼 [楼主]   回复  引用  查看    

2007-05-06 11:45 by webabcd      
@ayongwust
以ConfirmButtons为例

ConfirmButtons是个属性,该属性是一个实体对象的集合
必需的元数据
PersistenceMode(PersistenceMode.InnerProperty),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),

具体可查看msdn

ConfirmButtons类要实现CollectionBase接口
其每一项就是一个ConfirmButton对象

#22楼    回复  引用    

2007-05-06 14:30 by ayongwust [未注册用户]
@webabcd

明白;太感谢你了。
祝你五一快乐! 天天快乐!

#23楼 [楼主]   回复  引用  查看    

2007-05-06 21:14 by webabcd      
@ayongwust
:)
不谢

五一快乐不了了,一直加班,好在明天终于可以休息一天了

#24楼    回复  引用    

2007-05-11 19:22 by laoderfj [未注册用户]
谢谢

#25楼 [楼主]   回复  引用  查看    

2007-05-11 21:06 by webabcd      
@laoderfj
:)
不谢

#26楼    回复  引用    

2007-05-19 10:28 by steven [未注册用户]
用ado.net怎么办?学习中

#27楼 [楼主]   回复  引用  查看    

2007-05-19 19:32 by webabcd      
@steven
“用ado.net怎么办?”是什么意思?

#28楼    回复  引用    

2007-05-19 20:54 by Bill [未注册用户]
谢谢作者共享
我现在也准备写个控件 ,但我想作者的方法,可能性能不是很理想,
我想如果这些功能本来可以用JAVASCRIPT做的,为什么不用他来做呢
我们 把脚本写好,再做成控件,我想效果可能要好 ,因为AJAX的控件也是
这么包装的!

#29楼 [楼主]   回复  引用  查看    

2007-05-19 22:31 by webabcd      
@Bill
嗯,最开始是这么写的
/// <summary>
/// 构造函数
/// </summary>
public SmartGridView()
{
this.PreRender += new EventHandler(SmartGridView_PreRender);
}

/// <summary>
/// PreRender
/// </summary>
/// <param name="sender">sender</param>
/// <param name="e">e</param>
void SmartGridView_PreRender(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(this._cssClassMouseOver))
{
// 注册一个客户端变量
if (!Page.ClientScript.IsClientScriptBlockRegistered("jsRowClass"))
{
Page.ClientScript.RegisterClientScriptBlock(
this.GetType(),
"jsRowClass",
@"<script type=""text/javascript"">var yy_RowClass</script>"
);
}
}
}

/// <summary>
/// OnRowDataBound
/// </summary>
/// <param name="e"></param>
protected override void OnRowDataBound(GridViewRowEventArgs e)
{

if (e.Row.RowType == DataControlRowType.DataRow)
{
// _cssClassMouseOver不是空则执行
if (!string.IsNullOrEmpty(this._cssClassMouseOver))
{
e.Row.Attributes.Add("onmouseover", "yy_RowClass=this.className;this.className='" + _cssClassMouseOver + "'");
e.Row.Attributes.Add("onmouseout", "this.className=yy_RowClass");
}
}

base.OnRowDataBound(e);
}

但是,后面实现“改变通过复选框选中的行的样式”的时候出现了问题,所以换了种写法

#30楼    回复  引用    

2007-06-04 01:01 by lessan [未注册用户]
谢谢啊~~~~~~~!很有用

#31楼 [楼主]   回复  引用  查看    

2007-06-04 08:01 by webabcd      
@lessan
:)
不谢

#32楼    回复  引用    

2007-06-19 14:24 by qianhuajuan [未注册用户]
我们现在做的项目就用到了扩展gridview控件。真的很神奇啊。谢谢。
努力学习!

#33楼 [楼主]   回复  引用  查看    

2007-06-19 17:57 by webabcd      
@qianhuajuan
:)
不谢

确实,干这行,每天都有东西要学啊

#34楼    回复  引用  查看    

2007-06-20 15:38 by jhtchina      
谢谢你
学习

#35楼 [楼主]   回复  引用  查看    

2007-06-20 17:13 by webabcd      
@jhtchina
:)
不谢
大家多交流

#36楼    回复  引用    

2007-08-24 11:19 by 兄弟能发一份给我不 [未注册用户]
兄弟,功能很强大,代码也写得很精简,我试用了一下,设计模式下会死机,而且要实现girdview的扩展功能,需要在开发时加一些额外代码(比如加div等),能否封装一起,在项目开发时,做到最精简,减少开发者的工作量;

pghdragon@talkweb.com.cn

#37楼 [楼主]   回复  引用  查看    

2007-08-24 14:04 by webabcd      
@兄弟能发一份给我不
“设计模式下会死机”?
不会啊

“要实现girdview的扩展功能,需要在开发时加一些额外代码(比如加div等),能否封装一起,在项目开发时,做到最精简,减少开发者的工作量”
感觉没什么必要
还是根据自定义扩展功能的需求再做增加吧

#38楼    回复  引用    

2007-09-06 10:14 by 刘冰 [未注册用户]
我是个菜鸟,刚从asp转到asp.net来学习,今天算是长见识了。对初学者,大家有什么好的建议吗?谢谢

#39楼 [楼主]   回复  引用  查看