XuGang

记录一个程序员的成长

 

创建可拖动列的DataGrid_学习笔记(1)

最近看了孟宪会的BLOG,里面关于DataGrid(VS2005里面叫GridView)是我比较感兴趣的。大概是我对这个学习和使用得比较多的缘故。创建可拖动列的DataGrid让我个人比较喜欢,但孟宪会并没有怎么详细讲解,提供了一个下载地址就完事情,所以我产生了分析一下的念头。

效果图:


先提供下载地址给大家:
http://www.Planet-Source-Code.com/vb/scripts/ShowCode.asp?txtCodeId=1510&lngWId=10


补记:

谢谢@DeViL→Ivy 给我提出宝贵的意见,我将DropDataGrid.aspx 文件关键的代码解释一下:

创建了一个 DataSet 为:_dsContacts
创建了一个class变量    nColumn As Int32  
   nColumn = _dsContacts.Tables("Contact").Columns.Count  //nColumn 为表 "Contact"的列数

 If Not Page.IsPostBack Then
         ' 只在页面首次请求时才进行数据绑定
        Dim dv As DataView = New DataView(_dsContacts.Tables("Contact"))
//根据DataSet 的Tables("Contact") 创建DataView dv

//下面是在MyTable_ItemCreated事件里:
'//能否拖放的关键一句    
For i = 0 To nColumn - 1
      e.Item.Cells(i).Attributes.Add("Width","200")
Next

<asp:DataGrid id="MyTable"    。。。//在DataGrid之中,下面这句话直接引用tableAct.htc这个文件

       Style="behavior:url(tableAct.htc);"

至于mxh.xml 源文件和 tableAct.htc 源文件就没有必要解释了,相信能看懂的就能看懂,
看不懂的话,我解释也起不了作用了,呵呵; )

大家只要把DropDataGrid.aspx,mxh.xml,tableAct.htc这三个文件和我在下面提供的三个gif图片放在一起并放在aspx项目的根目录下就可以调试运行。


DropDataGrid.aspx 的文件如下:

<%@ Page Language="VB" EnableViewState = "false"%>
<%@ import namespace="System" %>
<%@ import namespace="System.Data" %>
<%@ import namespace="System.Web.UI" %>
<%@ import namespace="System.Web.UI.WebControls" %>
<%@ import namespace="System.Xml" %>
<script language="VB" runat="server">
    
Public nColumn As Int32 = 0
    
Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
        
Dim _dsContacts As DataSet
      
' 装载XML数据原,注意:这里与数据原类型没有关系,换成数据库也是适用的
      _dsContacts = New DataSet()
      _dsContacts.ReadXml(Server.MapPath(
"mxh.xml"))
      
Dim dcPk As DataColumn() = {_dsContacts.Tables("Contact").Columns("Email")}
      _dsContacts.Tables(
"Contact").PrimaryKey = dcPk
        nColumn 
= _dsContacts.Tables("Contact").Columns.Count
        MyTable.Attributes.Add(
"dragcolor","gray")
        MyTable.Attributes.Add(
"slcolor","#ffffcc")
        MyTable.Attributes.Add(
"hlcolor","#BEC5DE")

      
If Not Page.IsPostBack Then
         
' 只在页面首次请求时才进行数据绑定
        Dim dv As DataView = New DataView(_dsContacts.Tables("Contact"))
        dv.Sort 
= "LastName, FirstName"
        MyTable.DataSource 
= dv
        MyTable.DataBind()
      
End If
    
End Sub
    
Sub MyTable_ItemCreated(sender As Object, e As DataGridItemEventArgs)
        
If e.Item.ItemType=ListItemType.Header Then
            
Dim i As Int32
            
For i = 0 To nColumn - 1
                
'//能否拖放的关键一句
                e.Item.Cells(i).Attributes.Add("Width","200")
            
Next
        
End If
    
End Sub
</script>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
  
<HEAD>
    
<meta name="GENERATOR" Content="Microsoft Visual Studio 7.0">
    
<META http-equiv="Content-Type" content="text/html; charset=gb2313">
    
<title>DataGrid拖动的例子</title>
    
<meta name="CODE_LANGUAGE" Content="VB">
    
<meta name="vs_defaultClientScript" content="JavaScript">
    
<meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
  
</HEAD>
  
<body>
  
<div align="center"><b>DataGrid拖动列、排序的例子,放在aspx运行目录下即可直接运行。</b></div>
    
<form id="idbSample" method="post" runat="server" class="SubHeading">
      
<asp:DataGrid id="MyTable" runat="server" AutoGenerateColumns="True"
       Style
="behavior:url(tableAct.htc);" Width="100%" Cellpadding = "3"
       OnItemCreated
="MyTable_ItemCreated" BorderColor="#000099">
                
<HeaderStyle Font-Bold="True" BackColor="#ffcc66" HorizontalAlign="center"></HeaderStyle>
      
</asp:DataGrid>
    
</form>
  
</body>
</HTML>


mxh.xml 的文件如下:
<?xml version="1.0" encoding="gb2312" standalone="yes"?>
<Contacts>
  
<Contact>
    
<Email>myaddress@mycompany.com</Email>
    
<FirstName>E章</FirstName>
    
<LastName>孟子</LastName>
    
<Manager>0</Manager>
  
</Contact>
  
<Contact>
    
<Email>youraddress@yourcompany.com</Email>
    
<FirstName>宪会</FirstName>
    
<LastName></LastName>
    
<Manager>1</Manager>
  
</Contact>
  
<Contact>
    
<Email>mm@mmm.mm</Email>
    
<FirstName>Lover</FirstName>
    
<LastName>Net</LastName>
    
<Manager>0</Manager>
  
</Contact>
  
<Contact>
    
<Email>xxx@xxxx.xx</Email>
    
<FirstName>NET开发者园地</FirstName>
    
<LastName>Net</LastName>
    
<Manager>0</Manager>
  
</Contact>
  
<Contact>
    
<Email>hhh@hhh.hh</Email>
    
<FirstName>XML开发者园地</FirstName>
    
<LastName>Net</LastName>
    
<Manager>1</Manager>
  
</Contact>
</Contacts>


tableAct.htc 的文件如下:
<public:event name="onrowselect" ID=rowSelect />
<public:property name="hlColor" />
<public:property name="slColor" />
<public:property name='dragColor' />

<PUBLIC:ATTACH EVENT="ondetach" ONEVENT="cleanup()" />
<public:attach     event=oncontentready onevent="init();" />

<script language=jscript>
var currRow = -1;
var selRow = -1;

if (element.tagName == 'TABLE')
{
    element.attachEvent('onmouseover', onMouseOver);
    element.attachEvent('onmouseout', onMouseOut);
    element.attachEvent('onclick', onClick);
}

else
{
    alert(
"错误");
}


function cleanup()
{
    hilite(
-1);

    element.detachEvent('onmouseover', onMouseOver);
    element.detachEvent('onmouseout', onMouseOut);
    element.detachEvent('onclick', onClick);
}


function onClick()
{
    srcElem 
= window.event.srcElement;
    
while (srcElem.tagName != "TR" && srcElem.tagName != "TABLE")
        srcElem 
= srcElem.parentElement;

    
if(srcElem.tagName != "TR"return;

    
if(srcElem.rowIndex == 0 ) return;

    
if (selRow != -1) selRow.runtimeStyle.backgroundColor = '';

    srcElem.runtimeStyle.backgroundColor 
= slColor;
    selRow 
= srcElem;

    
var oEvent     = createEventObject();
    oEvent.selected 
= selRow;
    rowSelect.fire(oEvent);
}


//找到所在的行,然后决定是否改变背景颜色
function onMouseOver()
{
    srcElem 
= window.event.srcElement;
    
//crawl up to find the row
    while (srcElem.tagName != "TR" && srcElem.tagName != "TABLE")
        srcElem 
= srcElem.parentElement;

    
if(srcElem.tagName != "TR"return;

    
if (srcElem.rowIndex > 0)
        hilite(srcElem);
    
else
        hilite(
-1);

}


function onMouseOut()
{
    hilite(
-1-1);
}


function hilite(newRow)
{
    
if (hlColor != null )
    
{
        
if (currRow != -1 && currRow!=selRow)
        
{
            currRow.runtimeStyle.backgroundColor 
= '';
        }


        
if (newRow != -1 && newRow!=selRow)
        
{
            newRow.runtimeStyle.backgroundColor 
= hlColor;
        }

    }

    currRow 
= newRow;
}


var tbody=null;
var theadrow=null;
var colCount = null;


var reverse = false;
var lastclick = -1;

var arrHitTest = new Array();
var bDragMode = false;
var objDragItem;
var arrHitTest = new Array();
var iArrayHit = false;

function init() {
    
var MytHead = element.createTHead();
    MytHead.appendChild(element.rows[
0]);
    element.deleteRow(
1);
    tbody 
= element.tBodies(0);
    
if (!tbody) return;
    
var thead = element.tHead;
    
if (!thead)  return;

    theadrow 
= thead.children[0]; //假定只有一行Head
    if (theadrow.tagName != "TR"return;

    theadrow.runtimeStyle.cursor 
= "hand";

    colCount 
= theadrow.children.length;
    
var l, clickCell;
  
var cx=0;
  
var cy=0;
  
var c;

    
for (var i=0; i<colCount; i++)
    
{
        l
=document.createElement("IMG");
        l.src
="dude07232001blank.gif";
        l.id
="srtImg";
        l.width
=25;
        l.height
=11;

        clickCell 
= theadrow.children[i];
        clickCell.selectIndex 
= i;
        clickCell.insertAdjacentElement(
"beforeEnd", l)
        clickCell.attachEvent(
"onclick", doClick);

        arrHitTest[i] 
= new Array();

        c 
= clickCell.offsetParent;


       
if(cx == 0 && cy == 0 )
       
{
            
while (c.offsetParent != null{
                  cy 
+= c.offsetTop;
                  cx 
+= c.offsetLeft;
                  c 
= c.offsetParent;
        }

    }


    arrHitTest[i][
0= cx + clickCell.offsetLeft;
    arrHitTest[i][
1= cy + clickCell.offsetTop;
    arrHitTest[i][
2= clickCell;
    arrHitTest[i][
3= cx + clickCell.offsetLeft + eval(clickCell.width);

    clickCell.attachEvent(
"onmousedown",onMouseDown);
    }


  defaultTitleColor 
= theadrow.children[0].currentStyle.backgroundColor;

  element.document.attachEvent(
"onmousemove",onMouseMove);
  element.document.attachEvent(
"onmouseup",onMouseUp);
  element.document.attachEvent(
"onselectstart",onSelect);
}


function doClick(e)
{
    
var clickObject = e.srcElement;

    
while (clickObject.tagName != "TD")
    
{
        clickObject 
= clickObject.parentElement;
    }


    
var imgcol= theadrow.all('srtimg');
    
for(var x = 0; x < imgcol.length; x++)
        imgcol[x].src 
= "dude07232001blank.gif";

    
if(lastclick == clickObject.selectIndex)
    
{
        
if(reverse == false)
        
{
            clickObject.children[
0].src = "dude07232001down.gif";
              reverse 
= true;
        }

        
else
        
{
            clickObject.children[
0].src = "dude07232001up.gif";
            reverse 
= false;
        }

    }

    
else
    
{
        reverse 
= false;
        lastclick 
= clickObject.selectIndex;
        clickObject.children[
0].src = "dude07232001up.gif";
    }


    insertionSort(tbody, tbody.rows.length
-1,  reverse, clickObject.selectIndex);
}


function insertionSort(t, iRowEnd, fReverse, iColumn)
{
    
var iRowInsertRow, iRowWalkRow, current, insert;
    
for ( iRowInsert = 0 + 1 ; iRowInsert <= iRowEnd ; iRowInsert++ )
    
{
        
if (iColumn) {
        
iftypeof(t.children[iRowInsert].children[iColumn]) != "undefined")
                   textRowInsert 
= t.children[iRowInsert].children[iColumn].innerText;
        
else
            textRowInsert 
= "";
        }
 else {
           textRowInsert 
= t.children[iRowInsert].innerText;
        }


        
for ( iRowWalk = 0; iRowWalk <= iRowInsert ; iRowWalk++ )
        
{
            
if (iColumn) {
            
if(typeof(t.children[iRowWalk].children[iColumn]) != "undefined")
                textRowCurrent 
= t.children[iRowWalk].children[iColumn].innerText;
            
else
                textRowCurrent 
= "";
            }
 else {
            textRowCurrent 
= t.children[iRowWalk].innerText;
            }


        current 
= textRowCurrent;
        insert  
= textRowInsert;

        
if ( !isNaN(current) ||  !isNaN(insert))
        
{
            current
= eval(current);
            insert
= eval(insert);
        }

        
else
        
{
            current    
= current.toLowerCase();
            insert    
= insert.toLowerCase();
        }



            
if ( (   (!fReverse && insert < current)
                 
|| ( fReverse && insert > current) )
                 
&& (iRowInsert != iRowWalk) )
            
{
            eRowInsert 
= t.children[iRowInsert];
                eRowWalk 
= t.children[iRowWalk];
                t.insertBefore(eRowInsert, eRowWalk);
                iRowWalk 
= iRowInsert; // done
            }

        }

    }

}



function InitHeader()
{
  
var cx=0;
  
var cy=0;
  
var c;

  
for (i=0; i<colCount ; i++{

    
var clickCell = theadrow.children[i];
    clickCell.selectIndex 
= i;
    c 
= clickCell.offsetParent;

    
if(cx == 0 && cy == 0 )
    
{
        
while (c.offsetParent != null{
                  cy 
+= c.offsetTop;
                  cx 
+= c.offsetLeft;
                  c 
= c.offsetParent;
        }

    }


    arrHitTest[i][
0= cx + clickCell.offsetLeft;
    arrHitTest[i][
1= cy + clickCell.offsetTop;
    arrHitTest[i][
2= clickCell;
    arrHitTest[i][
3= cx + clickCell.offsetLeft + eval(clickCell.width);
  }

}


function onSelect()
{
    
return false;
}


function ChangeHeader(iChange)
{
    
for(var y = 0; y < arrHitTest.length; y++)
    
{
    
if (arrHitTest[y][2].currentStyle.backgroundColor == dragColor)
        arrHitTest[y][
2].style.backgroundColor = defaultTitleColor;
    }


    
if(iChange == "-1"return;

    arrHitTest[iChange][
2].style.backgroundColor = dragColor;
}


function onMouseUp(e)
{
    
if(!bDragMode)    return;
    bDragMode 
= false;

    
var iSelected = objDragItem.selectIndex;

    objDragItem.removeNode(
true);
    objDragItem 
= null;

    ChangeHeader(
-1);

    
if( (iArrayHit - 1< 0 || iSelected < 0return;

    CopyRow(iSelected, (iArrayHit 
- 1) );

    iSelected 
= 0;
    iArrayHit 
= -1;
}


function onMouseDown(e)
{
    bDragMode    
= true;
    
var src = e.srcElement;
    
var c = e.srcElement;

    
while (src.tagName != "TD")
        src 
= src.parentElement;
    objDragItem 
= document.createElement("DIV");
    objDragItem.innerHTML        
= src.innerHTML;
    objDragItem.style.height    
= src.currentStyle.height;
    objDragItem.style.width     
= src.currentStyle.width;
    objDragItem.style.background     
= src.currentStyle.backgroundColor;
    objDragItem.style.fontColor    
= src.currentStyle.fontColor;
    objDragItem.style.position     
= "absolute";
    objDragItem.selectIndex        
= src.selectIndex;
    
while (c.offsetParent != null)
        
{
        objDragItem.style.y 
+= c.offsetTop;
        objDragItem.style.x 
+= c.offsetLeft;
        c 
= c.offsetParent;
    }

     objDragItem.style.borderStyle    
= "outset";
    objDragItem.style.display    
= "none";
    src.insertBefore(objDragItem);
}


function onMouseMove(e)
{
    
if(!bDragMode || !objDragItem) return;

    
var midWObj = objDragItem.style.posWidth / 2;
    
var midHObj = 12;

 
var intTop = e.clientY + element.document.body.scrollTop;
 
var intLeft = e.clientX + element.document.body.scrollLeft;


    
var cx=0,cy=0;
    
var elCurrent = objDragItem.offsetParent;
               
while (elCurrent.offsetParent != null{
                  cx 
+= elCurrent.offsetTop;
                  cy 
+= elCurrent.offsetLeft;
                  elCurrent 
= elCurrent.offsetParent;
               }



      objDragItem.style.pixelTop  
= intTop  - cx - midHObj;
      objDragItem.style.pixelLeft 
= intLeft - cy - midWObj;


    
if(objDragItem.style.display == "none") objDragItem.style.display = "";

    iArrayHit 
= CheckHit(intTop , intLeft , e);

    e.cancelBubble 
= false;
    e.returnValue 
= false;
}


function CheckHit(x,y,e)
{
    midWObj 
= objDragItem.style.posWidth / 2;
    midHObj 
= 12;

    
if( ((x) > (arrHitTest[0][1+ 20) ) || ( (x) < (arrHitTest[0][1]) ) )
    
{
        ChangeHeader(
-1);
        
return -1;
    }


    
for(var i=0; i < colCount; i++)
    
{
        
if( (y) > (arrHitTest[i][0]) && (y) < (arrHitTest[i][3] )) //+ 100))
        {
            ChangeHeader(i);
            
return i + 1;
        }

    }

    
return -1;
}


function CopyRow(from, to)
{
    
if(from == to) return;


    
var origfrom = from;
    
var origto = to;
    
var iDiff = 0;

    
if( from > to )
    
{

        iDiff 
= from - to;

        
var saveObj     = theadrow.children[from].innerHTML;
        
var saveWidth     = theadrow.children[from].width;

        
for(var i = 0 ; i < iDiff; i++)
        
{
            theadrow.children[from].innerHTML 
= theadrow.children[from - 1].innerHTML;
            theadrow.children[from].width 
= theadrow.children[from - 1].width;
            from
--;
        }

        theadrow.children[to].innerHTML     
= saveObj;
        theadrow.children[to].width 
= saveWidth;

    }

    
else
    
{

        iDiff 
= to - from;

        
var saveObj = theadrow.children[from].innerHTML;
        
var saveWidth     = theadrow.children[from].width;

        
for(var i = 0 ; i < iDiff; i++)
        
{
            theadrow.children[from].innerHTML 
= theadrow.children[from + 1].innerHTML;
            theadrow.children[from].width 
= theadrow.children[from + 1].width;
            from
++;
        }


        theadrow.children[to].innerHTML     
= saveObj;
        theadrow.children[to].width 
= saveWidth;
    }




    
for(var i = 0 ; i < theadrow.children.length; i++)
            theadrow.children[i].selectIndex 
= i;



    InitHeader();
    
for ( var iRowInsert = 0 ; iRowInsert < tbody.rows.length; iRowInsert++ )
    
{
        from 
= origfrom;
        to 
= origto;
        
if( from > to )
        
{
            iDiff 
= from - to;
            
var saveObj = tbody.children[iRowInsert].children[from].innerHTML
            
for(var i = 0 ; i < iDiff; i++)
            
{
                tbody.children[iRowInsert].children[from].innerHTML 
= tbody.children[iRowInsert].children[from - 1].innerHTML;
                from
--;
            }

            tbody.children[iRowInsert].children[to].innerHTML 
= saveObj;

        }

        
else
        
{
            iDiff 
= to - from;
            
var saveObj = tbody.children[iRowInsert].children[from].innerHTML
            
for(var i = 0 ; i < iDiff; i++)
            
{
                tbody.children[iRowInsert].children[from].innerHTML 
= tbody.children[iRowInsert].children[from + 1].innerHTML;
                from
++;
            }

            tbody.children[iRowInsert].children[to].innerHTML 
= saveObj;
        }

    }

}


</script>

附加了三张gif的小图片,在原文件里面有下载:
01 02 03

 

posted on 2007-09-13 11:36  钢钢  阅读(2403)  评论(3编辑  收藏  举报

导航