自己写的DataGrid.新增功能“滚动条、固定列头和首列和最后一行、用鼠标调整列宽”。大家都来砸呀……

时间:2023-01-26 23:02:15
新增功能:
1、滚动条
2、固定列头、首列和最后一行
3、用鼠标调整列宽

胡乱写的东西,也没有经过仔细测试,不知道对大家有用没有,还请多提宝贵意见,有什么只管砸来就!
唉哟,这么就有鸡蛋飞来啦……

注意事项:
1、使用新增功能2时,要设置其背景色。否则,它就是透明的,就能看到它下面的内容。
2、用鼠标调整时,不要太靠近边线,否则,不容易调整。
**********************************
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Drawing;

namespace SyDG
{
/// <summary>
/// WebCustomControl1 的摘要说明。
/// </summary>
[DefaultProperty("Text"), 
ToolboxData("<{0}:SyDataGrid runat=server></{0}:SyDataGrid1>")]
public class SyDataGrid : System.Web.UI.WebControls.DataGrid
{
private bool showScroll=true;
[Category("属性"),Description("是否显示滚动条"),DefaultValue(true)]
public bool ShowScroll
{
get
{
return showScroll;
}
set
{
showScroll=value;
}
}
private string scrollClassName="";
[Category("属性"),Description("滚动条样式,也可设置外边框样式"),DefaultValue("")]
public string ScrollClassName
{
get
{
return scrollClassName;
}
set
{
scrollClassName=value;
}
}
private bool fixFoot=false;
[Category("属性"),Description("是否固定显示最后一行在底部"),DefaultValue(false)]
public bool FixFoot
{
get
{
return fixFoot;
}
set
{
fixFoot=value;
}
}
private bool fixFirst=true;
[Category("属性"),Description("是否固定显示首列在左侧"),DefaultValue(true)]
public bool FixFirst
{
get
{
return fixFirst;
}
set
{
fixFirst=value;
}
}
private bool resizeColumn=true;
[Category("属性"),Description("是否允许用鼠标调整列宽"),DefaultValue(true)]
public  bool ResizeColumn
{
get
{
return resizeColumn;
}
set
{
resizeColumn=value;
}
}
private Unit tableWidth=new Unit(null);
[Category("属性"),Description("用来显示数据的表格的实际宽度")]
public Unit TableWidth
{
get{
return tableWidth;
}
set{
tableWidth=value;
}
}
private string ColorToString(Color color)
{
if(color.IsEmpty)
return "#ffffff";
else
{
if(color.IsKnownColor)
return color.Name;
else
return "#"+color.Name.Substring(2);
}
}

31 个解决方案

#1


/// <summary> 
/// 将此控件呈现给指定的输出参数。
/// </summary>
/// <param name="output"> 要写出到的 HTML 编写器 </param>
protected override void Render(HtmlTextWriter output)
{
output.WriteLine("<!--****************^_^**************输出脚本开始****************^_^**************-->");
//*******************************************************
if(this.ShowScroll)//如果显示滚动条,输出Div
{
//判断在当前页面中是否已经输出过该脚本
if(this.Page.IsStartupScriptRegistered("SyDG_JScript")==false)
{
this.Page.RegisterStartupScript("SyDG_JScript","");//设置输出脚本标记
string script="";
script += @"<script language=javascript>
function SyDG_doscroll(div)
{
table=div.getElementsByTagName('TABLE')[0];";
//如果固定首“列”
if(this.FixFirst)
script +=@"
for(i=table.rows.length-1;i>=0;i--)
{
table.rows[i].cells[0].style.position='relative';
if(i!=table.rows.length-1)
table.rows[i].cells[0].style.borderBottomStyle='none';
table.rows[i].cells[0].style.left=div.scrollLeft;
}
";
//设置首“行”不动
script += @"
for(i=0;i<table.rows[0].cells.length;i++)
{
if(i!=table.rows[0].cells.length-1 && i!=0)
table.rows[0].cells[i].style.borderRightStyle='none';
table.rows[0].cells[i].style.zIndex=9999-i;
table.rows[0].cells[i].style.position='relative';
table.rows[0].cells[i].style.top=div.scrollTop;
}
";
//如果固定尾行,则输出脚本
if(this.fixFoot) script += "SyDG_setBottomTr(table.rows[table.rows.length-1]);";

script +=" }";
if(this.ResizeColumn)
script +=
@"function SyDG_moveOnTd(td)
{
if(event.offsetX>td.offsetWidth-10)
td.style.cursor='w-resize';
else
td.style.cursor='default';
if(td.mouseDown!=null && td.mouseDown==true)
{
if(td.oldWidth+(event.x-td.oldX)>0)
td.width=td.oldWidth+(event.x-td.oldX);
td.style.width=td.width;
td.style.cursor='w-resize';

table=td;
while(table.tagName!='TABLE') table=table.parentElement;
table.width=td.tableWidth+(td.offsetWidth-td.oldWidth);table.style.width=table.width;
}
}
function SyDG_downOnTd(td)
{
if(event.offsetX>td.offsetWidth-10)
{
td.mouseDown=true;
td.oldX=event.x;
td.oldWidth=td.offsetWidth;
table=td;while(table.tagName!='TABLE')table=table.parentElement;
td.tableWidth=table.offsetWidth;
}
}";
if(this.FixFoot)//如果固定尾行,则输出该脚本函数
script +=@"
function SyDG_setBottomTr(tr)//设置尾行不动
{
div=tr;table=tr;
while(table.tagName!='TABLE')table=table.parentElement;
//while(div.tagName!='DIV')div=div.parentElement;
div=table.parentElement;
//tr.style.position='relative';
//tr.style.top=div.offsetHeight+div.scrollTop-table.offsetHeight-16;
for(i=0;i<tr.cells.length;i++)
{

tr.cells[i].style.zIndex=9999-i;
tr.cells[i].style.position='relative';
if(i!=tr.cells.length-1 && i!=0)
tr.cells[i].style.borderRightStyle='none';
tr.cells[i].style.top=div.offsetHeight+div.scrollTop-table.offsetHeight-16;
}
}";
script += "</script>";

output.Write(script);//输出脚本
}
string div=@"<div id='"+this.ID+"_div' style='OVERFLOW: scroll;width:"+this.Width.Value;
if(this.Width.Type==UnitType.Percentage)//宽是百分比
div += "%;";
else
div +="px;";
div += "height:"+this.Height.Value;
if(this.Height.Type==UnitType.Percentage)
div +="%;";
else
div += "px;";
div += "' onscroll='SyDG_doscroll(this)' onresize='this.onscroll()' class='"+this.ScrollClassName+"'>";
output.Write(div);
}
output.WriteLine("<!--****************^_^**************输出脚本结束****************^_^**************-->");
output.WriteLine("<!--****************^_^**************输出控件开始****************^_^**************-->");
if(this.ShowScroll)
this.Attributes.Add("onresize","this.parentElement.onscroll()");
//***************************************************
Unit width=this.Width;Unit height=this.Height;
this.Width=this.TableWidth;this.Height=new Unit(null);
base.Render(output);//调用基类函数输出数据
this.Width=width;this.Height=height;
//***************************************************
output.WriteLine("<!--****************^_^**************输出控件结束****************^_^**************-->");
if(this.ShowScroll)
{
if(this.FixFoot)//如果固定最后一行,输出固定行脚本
{
output.Write(@"<script language=javascript>
table=document.all."+this.ID+@"_div.getElementsByTagName('TABLE')[0];
SyDG_setBottomTr(table.rows[table.rows.length-1]);
</script>");
}
output.WriteLine("</div>");//输出DIV结束标记
}
}
protected override void OnItemCreated(DataGridItemEventArgs e)
{
if(e.Item.ItemType == ListItemType.Pager)
{
for(int i=0;i<e.Item.Cells.Count;i++)
{
e.Item.Cells[i].BackColor=e.Item.BackColor;
//e.Item.Cells[i].Attributes.Add("onclick","alert('Footer')");
}
}
//设置页眉事件,使之可以用鼠标调整列宽
else if(e.Item.ItemType == ListItemType.Header)
{
if(this.ResizeColumn)//如果允许改变列宽
{
for(int i=0;i<e.Item.Cells.Count;i++)
{
e.Item.Cells[i].Attributes.Add("onmousemove","SyDG_moveOnTd(this)");
e.Item.Cells[i].Attributes.Add("onmousedown","SyDG_downOnTd(this)");
e.Item.Cells[i].Attributes.Add("onmouseup","this.mouseDown=false");
e.Item.Cells[i].Attributes.Add("onmouseout","this.mouseDown=false");
}
}
}

}
}
}

#2


老大,怎么不做好打包下载,这样让人有点眼花:)

#3


up!

#4


up

#5


good

#6


高!

#7


我来用一下,以前自己做的只是操作数据库还没做过用鼠标调整列宽的呢

#8


谢过

#9


不错。
不过如果想让datagrid自动出现滚动条的话,也可以直接把datagrid放在一个div里。:)

#10


up

#11


收藏

#12


看看,谢谢了!!

#13


收藏,谢谢了!!

#14


对很多人有用,以前有很多人提问过

#15


厉害啊!收藏

#16


up

#17


最好能做成一个标准的控件,让我们能够直接引用。

#18


顶,
老外有个SuperGrid,跟你的功能强一点
能托拽列,让起交换位置,列头有排序功能

#19


加油啊!

#20


打包,发个给我吧!
谢谢了
vabug@sina.com

#21


谢谢各位支持
其实这个控件也没太大的技术问题。只不过是使用脚本控制而已
最近比较忙,等过一段时间再重新整理一下。

#22


不错!收藏!

#23


共产主义

#24


#25


很好的思路,很好的东西。。。

#26


楼主在连接字符串的时候没有使用StringBuilder,太两费内存了。

#27


不错

#28


up

#29


good thanks

#30


如果能提供源碼就好啦。。

ghost@heshan.net

#31


我不明白,大家为什么那么喜欢微软的控件,难道非要成为微软的搬运工吗?

#1


/// <summary> 
/// 将此控件呈现给指定的输出参数。
/// </summary>
/// <param name="output"> 要写出到的 HTML 编写器 </param>
protected override void Render(HtmlTextWriter output)
{
output.WriteLine("<!--****************^_^**************输出脚本开始****************^_^**************-->");
//*******************************************************
if(this.ShowScroll)//如果显示滚动条,输出Div
{
//判断在当前页面中是否已经输出过该脚本
if(this.Page.IsStartupScriptRegistered("SyDG_JScript")==false)
{
this.Page.RegisterStartupScript("SyDG_JScript","");//设置输出脚本标记
string script="";
script += @"<script language=javascript>
function SyDG_doscroll(div)
{
table=div.getElementsByTagName('TABLE')[0];";
//如果固定首“列”
if(this.FixFirst)
script +=@"
for(i=table.rows.length-1;i>=0;i--)
{
table.rows[i].cells[0].style.position='relative';
if(i!=table.rows.length-1)
table.rows[i].cells[0].style.borderBottomStyle='none';
table.rows[i].cells[0].style.left=div.scrollLeft;
}
";
//设置首“行”不动
script += @"
for(i=0;i<table.rows[0].cells.length;i++)
{
if(i!=table.rows[0].cells.length-1 && i!=0)
table.rows[0].cells[i].style.borderRightStyle='none';
table.rows[0].cells[i].style.zIndex=9999-i;
table.rows[0].cells[i].style.position='relative';
table.rows[0].cells[i].style.top=div.scrollTop;
}
";
//如果固定尾行,则输出脚本
if(this.fixFoot) script += "SyDG_setBottomTr(table.rows[table.rows.length-1]);";

script +=" }";
if(this.ResizeColumn)
script +=
@"function SyDG_moveOnTd(td)
{
if(event.offsetX>td.offsetWidth-10)
td.style.cursor='w-resize';
else
td.style.cursor='default';
if(td.mouseDown!=null && td.mouseDown==true)
{
if(td.oldWidth+(event.x-td.oldX)>0)
td.width=td.oldWidth+(event.x-td.oldX);
td.style.width=td.width;
td.style.cursor='w-resize';

table=td;
while(table.tagName!='TABLE') table=table.parentElement;
table.width=td.tableWidth+(td.offsetWidth-td.oldWidth);table.style.width=table.width;
}
}
function SyDG_downOnTd(td)
{
if(event.offsetX>td.offsetWidth-10)
{
td.mouseDown=true;
td.oldX=event.x;
td.oldWidth=td.offsetWidth;
table=td;while(table.tagName!='TABLE')table=table.parentElement;
td.tableWidth=table.offsetWidth;
}
}";
if(this.FixFoot)//如果固定尾行,则输出该脚本函数
script +=@"
function SyDG_setBottomTr(tr)//设置尾行不动
{
div=tr;table=tr;
while(table.tagName!='TABLE')table=table.parentElement;
//while(div.tagName!='DIV')div=div.parentElement;
div=table.parentElement;
//tr.style.position='relative';
//tr.style.top=div.offsetHeight+div.scrollTop-table.offsetHeight-16;
for(i=0;i<tr.cells.length;i++)
{

tr.cells[i].style.zIndex=9999-i;
tr.cells[i].style.position='relative';
if(i!=tr.cells.length-1 && i!=0)
tr.cells[i].style.borderRightStyle='none';
tr.cells[i].style.top=div.offsetHeight+div.scrollTop-table.offsetHeight-16;
}
}";
script += "</script>";

output.Write(script);//输出脚本
}
string div=@"<div id='"+this.ID+"_div' style='OVERFLOW: scroll;width:"+this.Width.Value;
if(this.Width.Type==UnitType.Percentage)//宽是百分比
div += "%;";
else
div +="px;";
div += "height:"+this.Height.Value;
if(this.Height.Type==UnitType.Percentage)
div +="%;";
else
div += "px;";
div += "' onscroll='SyDG_doscroll(this)' onresize='this.onscroll()' class='"+this.ScrollClassName+"'>";
output.Write(div);
}
output.WriteLine("<!--****************^_^**************输出脚本结束****************^_^**************-->");
output.WriteLine("<!--****************^_^**************输出控件开始****************^_^**************-->");
if(this.ShowScroll)
this.Attributes.Add("onresize","this.parentElement.onscroll()");
//***************************************************
Unit width=this.Width;Unit height=this.Height;
this.Width=this.TableWidth;this.Height=new Unit(null);
base.Render(output);//调用基类函数输出数据
this.Width=width;this.Height=height;
//***************************************************
output.WriteLine("<!--****************^_^**************输出控件结束****************^_^**************-->");
if(this.ShowScroll)
{
if(this.FixFoot)//如果固定最后一行,输出固定行脚本
{
output.Write(@"<script language=javascript>
table=document.all."+this.ID+@"_div.getElementsByTagName('TABLE')[0];
SyDG_setBottomTr(table.rows[table.rows.length-1]);
</script>");
}
output.WriteLine("</div>");//输出DIV结束标记
}
}
protected override void OnItemCreated(DataGridItemEventArgs e)
{
if(e.Item.ItemType == ListItemType.Pager)
{
for(int i=0;i<e.Item.Cells.Count;i++)
{
e.Item.Cells[i].BackColor=e.Item.BackColor;
//e.Item.Cells[i].Attributes.Add("onclick","alert('Footer')");
}
}
//设置页眉事件,使之可以用鼠标调整列宽
else if(e.Item.ItemType == ListItemType.Header)
{
if(this.ResizeColumn)//如果允许改变列宽
{
for(int i=0;i<e.Item.Cells.Count;i++)
{
e.Item.Cells[i].Attributes.Add("onmousemove","SyDG_moveOnTd(this)");
e.Item.Cells[i].Attributes.Add("onmousedown","SyDG_downOnTd(this)");
e.Item.Cells[i].Attributes.Add("onmouseup","this.mouseDown=false");
e.Item.Cells[i].Attributes.Add("onmouseout","this.mouseDown=false");
}
}
}

}
}
}

#2


老大,怎么不做好打包下载,这样让人有点眼花:)

#3


up!

#4


up

#5


good

#6


高!

#7


我来用一下,以前自己做的只是操作数据库还没做过用鼠标调整列宽的呢

#8


谢过

#9


不错。
不过如果想让datagrid自动出现滚动条的话,也可以直接把datagrid放在一个div里。:)

#10


up

#11


收藏

#12


看看,谢谢了!!

#13


收藏,谢谢了!!

#14


对很多人有用,以前有很多人提问过

#15


厉害啊!收藏

#16


up

#17


最好能做成一个标准的控件,让我们能够直接引用。

#18


顶,
老外有个SuperGrid,跟你的功能强一点
能托拽列,让起交换位置,列头有排序功能

#19


加油啊!

#20


打包,发个给我吧!
谢谢了
vabug@sina.com

#21


谢谢各位支持
其实这个控件也没太大的技术问题。只不过是使用脚本控制而已
最近比较忙,等过一段时间再重新整理一下。

#22


不错!收藏!

#23


共产主义

#24


#25


很好的思路,很好的东西。。。

#26


楼主在连接字符串的时候没有使用StringBuilder,太两费内存了。

#27


不错

#28


up

#29


good thanks

#30


如果能提供源碼就好啦。。

ghost@heshan.net

#31


我不明白,大家为什么那么喜欢微软的控件,难道非要成为微软的搬运工吗?