呵呵,好久没更新了。
前两个星期,都在试著将DataGrid变成可以拖动,并可以添加多表头的样子。拖动的可以了,多表头用最笨的办法也实现了,但是多表头并可以拖动却没有实现,比如,添加二级表头后,只有第一行表头可以拖动,第二行却不行。但是其间,我也是获益颇多。
1. 可以将一些鼠标等事件用JavaScript写到一个.htc的文件,然后使用下列方法(BEHAVIOR)调用:
(1) 方法一:
<asp:DataGrid ID="DataGrid1" runat="server" Style="behavior: url(draggrid.htc)">
</asp:DataGrid>
(2)方法二:
<style type="text/css">
.MoveDgd { BEHAVIOR: url(movegrid.htc)}
</style>
<asp:DataGrid ID="dgdMain" CssClass="MoveDgd" runat="server">
2. 鼠标移动到单元格上方时出现浮动提示:由于DataGrid可以拖动了,所以单元格的宽度就是个问题了。目标是:当单元格内的字符宽度(不是长度Length哦)大於单元格的宽度时,隐藏多余的字符,并且使用省略号代替,而且,当鼠标移动到DataGrid的某个单元格的上方时,如果单元格内的字符宽度(不是长度Length哦)大於单元格的宽度,则将完整内容作为提示显示出来。
(1) 在网上查找相关资料,发现原来使用CSS样式就可以实现了。
<style type="text/css">
. TextOver { text-overflow:ellipsis; overflow:hidden; white-space: nowrap; padding:2px; width:80% }
</style>
其中,TextOver为自定义的标识符。
这句是说当字符串的宽度超过单元格宽度的80%的时候,就以省略号显示多出部分。
然后在申明DataGrid的时候指定该样式:
<asp:DataGrid ID="DataGrid1" runat="server" CssClass="TextOver">
</asp:DataGrid>
(2) 这个方法对英文字母和数字都可以达到要求,但是对汉字就不能达到预期的效果,于是继续上网淘宝,发现了一段javascript可以实现:
<script language="javascript">
function changeTitle(obj)
{
if(obj.offsetWidth > obj.parentElement.offsetWidth)
{
obj.title = obj.innerText;
}
else
{
obj.title = "";
}
}
</script>
但是,方法中判断obj.offsetWidth > obj.parentElement.offsetWidth,但是直接使用的话,obj就是td了,那么obj.parentElement当然就是table了,所以这个条件总是不成立的,也就不会显示提示咯。
于是,我拼命的找资料,该怎么得到这些字符串的宽度,可惜的是,我奋斗了好久,都没有找到任何可行的方法,没办法,看来这样子是行不通的,只好换个方法。
所以我得在td的外面加一层标签<div></div>这样的话,当td中的字符串宽度超过td的宽度的时候,就能够显示提示了。试了下,居然通过。
首先,在DataGrid的ItemDataBound()事件中为表头外的所有单元格添加CssClass样式TextOver:
protected void dgdMain_ItemDataBound(object sender, DataGridItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Header)
{
}
else
{
for (int i = 0; i < e.Item.Cells.Count; i++)
{
e.Item.Cells[i].Attributes.Add("class", "TextOver");
}
}
}
然后,在填充DataGrid的时候,为td添加Div层:
public void FillDBGridFromDataSet(ref DataGrid DBGTemp, DataSet dstADO)
{
for (int intRow = 0; intRow <= dstADO.Tables[0].Rows.Count - 1; intRow++)
{
for (int intCol = 0; intCol <= DBGTemp.Columns.Count - 1; intCol++)
{
string[] strDBFieldNameWithCellType = DBGTemp.Columns[intCol].FooterText.Split('/u000F');
string strDBFieldName = strDBFieldNameWithCellType[0];//栏位名称
string strCellType = strDBFieldNameWithCellType[1]; //栏位型态
string strFieldType = strDBFieldNameWithCellType[2]; //按钮型态 LinkButton || PushButton
int intDec = Int32.Parse(strDBFieldNameWithCellType[3]);//币别小数位
if (strCellType == "1") //CheckBox
{
}
else if (strCellType == "3") //DataTime
{
…….
}
else if (strCellType == "4") //Numeric
{
………
}
else if (strCellType == "5") //5.String 型态
{
if (FindDBColumn(dstADO, strDBFieldName))
{
DBGTemp.Items[intRow].Cells[intCol].Text = dstADO.Tables[0].Rows[intRow][strDBFieldName].ToString();
/***************************************************************************************
* Desc:在单元格<td></td>中添加一层<div></div>标签
* 目的:注册onmouseover的事件,
* 用以判断单元格内字符串的宽度是否大于td的宽度(隐藏多余的字符并以...表示,并显示浮动提示)
****************************************************************************************/
string strDivStart = "<div style=/"white-space: nowrap;/" title=/"/" οnmοuseοver=/"changeTitle(this)/">";
string strDivEnd = "</div>";
string strTd = DBGTemp.Items[intRow].Cells[intCol].Text;
DBGTemp.Items[intRow].Cells[intCol].Controls.Add(new LiteralControl(strDivStart + strTd + strDivEnd));
}
}
else if (strCellType == "6") //6.COMBOBOX型态
{
………
}
else if (strCellType == "7") //Currency型态
{
………
}
else if (strCellType == "8") //LinkButton
{
………
}
else if (strCellType == "9") //PushButton
{
………
}
}
}
}
呵呵,又学了一招,原来MicroSoft给我们提供了这么多类可以使用,比如,我现在用到的添加标签:
string strDivStart = "<div style=/"white-space: nowrap;/" title=/"/" οnmοuseοver=/"changeTitle(this)/">";
string strDivEnd = "</div>";
string strTd = DBGTemp.Items[intRow].Cells[intCol].Text;
DBGTemp.Items[intRow].Cells[intCol].Controls.Add(new LiteralControl(strDivStart + strTd + strDivEnd));
这里,用到的是LiteralControl类,它表示 HTML 元素、文本和 ASP.NET 页中不需要在服务器上处理的任何其他字符串。
3. 先就这么多吧,周末愉快!