如何在DataGrid裡面產生捲軸

來源:互聯網
上載者:User
datagrid
我們在開發的時候一定遇到使用DataGrid的時候由於不想分頁(資料沒有那麼多)但是又顯示不在一頁裡面,此時我們希望在DataGrid裡面出現一個捲軸,可以上下滾動DataGrid裡面的資料而不用上下滾動頁面,由於寫本文的目的是為了說明如何?,所以對於細節性的問題讀者可以自己思考完成(比如:既要分頁又要滾動等等)。為了可以滾動DataGrid我們需要一個可以讓用戶端的Table滾動js指令碼(該js代碼我是從CodeProject上面下載的),但又不能滾動Table的題頭(也就是第一行)。我們都知道DataGrid在解釋到用戶端以後將會產生一個Table,但是這個Table是由<tr><td>組成的,我們的指令碼裡面是需要使用到Table的Thead和Tbody的(在大多數的用戶端的應用中都要用到此功能比如:用戶端的排序、以及列的托拽等等),因此我們接下來的任務就是如何為我們用戶端的這個DataGrid添加<thead><tbody>了。如果你對使用者的自訂控制項以及ASP.NET頁面的原理有所瞭解,我們知道控制項最後都是要呈現(Render)在頁面上的,因此我們可以重寫這個方法來完成DataGrid的自訂呈現。聽一聽真的有些嚇人,那麼複雜的控制項怎麼呈現?不要著急,首先我們建立一個自訂控制項如下所示:public class PowerDataGrid : System.Web.UI.WebControls.DataGrid
由此可以看出我們的控制項是繼承於DataGrid的,所以我們現在的這個控制項在不用寫一行代碼的情況下我們的這個控制項已經具有DataGrid的所有的功能。接下來我們要將我們準備的js代碼內嵌到我們的控制項裡,好讓放這個控制項的頁面上最終在用戶端都會有這段js代碼用來完成我們滾動的任務。為了完成這個工作我們要重寫預呈現的方法:
protected override void OnPreRender(System.EventArgs e)
{
base.OnPreRender(e);
ResourceManager manager = new ResourceManager( this.GetType() );
ResourceSet resources = manager.GetResourceSet(System.Globalization.CultureInfo.CurrentCulture, true, true);
if( !Page.IsClientScriptBlockRegistered( "SkySword.WebControl.PowerDataGrid Library" ) ) {
String script = resources.GetString("ScrollTable");
this.Page.RegisterClientScriptBlock("SkySword.WebControl.PowerDataGrid Library", script );
this.Page.RegisterStartupScript("SkySword.WebControls.PowerDataGrid Init", "<script>makeScrollableTable'" + this.ID + "',true,'auto');</script>" );
}
}
  在該方法中我們訪問了資源檔。哦!忘了說我們還要建立一個資源檔,用來儲存我們的js代碼。我們首先將資原始碼中對應ScrollTable的資料(一段js指令碼)註冊到用戶端的指令碼塊裡。最後我們為了可以初始化,將<script>makeScrollableTable('" + this.ID + "',true,'auto');</script>段指令碼註冊到頁面載入時開始執行(我想就應該和body裡面onload的方法一樣吧)。當你需要載入用戶端指令碼的時候使用該方法是個不錯的選擇。好了,用戶端指令碼也有了,剩下的就是處理我們的用戶端DataGrid了(也就是DataGrid呈現的用戶端Table)。為了可以呈現我們自己的DataGrid我們需要重寫呈現方法如下所示:
protected override void Render(HtmlTextWriter output)
{
output.Write(this.parseMarkup());
}
其中調用了一個parseMarkup的函數,改函數將產生一個輸出的指令碼(字串),該指令碼就是一個包含thead和tbody的Table。由於此方法只是由該控制項自己使用所以我們將它設定成私人的代碼如下:
private string parseMarkup(){
// 插入THead標籤和TBody標籤
StringWriter writer = new StringWriter();
HtmlTextWriter buffer = new HtmlTextWriter(writer);
base.Render(buffer);
string pMarkup = writer.ToString();

// 找到第一個table標籤的結尾也就是第一個>字元
pMarkup = pMarkup.Insert(pMarkup.IndexOf(">") + ">".Length, "<thead>");
// 將第一個tr閉區間用Thead包起來,現在第一個<thead>已經畫出來了需要畫
// 它的結尾</thead>和</tbody>,同樣找到第一個</tr>來插入</thead>和</tdoby>
pMarkup = pMarkup.Insert( pMarkup.IndexOf("</tr>") + "</tr>".Length,"</thead><tbody>");
// 在最後一個</table>的前面插入一個</tbody>就可以了。
pMarkup = pMarkup.Replace("</table>", "</tbody></table>");
return pMarkup;
}
在這個方法中我們首先執行個體化了一個StringWriter的對象writer,又用該對象為參數執行個體了一個HtmlTextWriter對象buffer,最關鍵的是我們調用了基類的Render用來將buffer裡面填滿要輸出的東西(一堆指令碼就是Table,如果你是用監視器查看裡面的內容就可以看到)。好了剩下的工作就是分析這個指令碼了,然後我們在該指令碼第一個出現<tr>的地方將這個<tr>替換成<thead>和<tr>後面的替換方法類似。最後我們將這個被我們替換和修改的Table輸出到用戶端,一切OK!

注意:用到StringWriter的原因就是它可以從buffer裡面儲存原始的字元比如:/t/n什麼的。 資源檔的配置方法:首先給你的工程添加一個資源檔,名字和你的控制項一樣,然後在該檔案中添加一下小節
<data name="ScrollTable">
<value><![CDATA[
<script language = 'javascript'>

var container = new Array();
var onResizeHandler;

function scrollbarWidth(){
var w;

if (! document.body.currentStyle) document.body.currentStyle = document.body.style;

if (document.body.currentStyle.overflowY == 'visible' || document.body.currentStyle.overflowY == 'scroll'){
w = document.body.offsetWidth - document.body.clientLeft - document.body.clientWidth;
}else{
win = window.open("about:blank", "_blank", "top=0,left=0,width=100,height=100,scrollbars=yes");
win.document.writeln('scrollbar');
w = win.document.body.offsetWidth - win.document.body.clientLeft - win.document.body.clientWidth;
win.close();
}



return w;
}

function getActualWidth(e){
if (! e.currentStyle) e.currentStyle = e.style;

return e.clientWidth - parseInt(e.currentStyle.paddingLeft) - parseInt(e.currentStyle.paddingRight);
}

function findRowWidth(r){
for (var i=0; i < r.length; i++){
r[i].actualWidth = getActualWidth(r[i]);
}
}

function setRowWidth(r){
for (var i=0; i < r.length; i++){
r[i].width = r[i].actualWidth;
r[i].innerHTML = '<span style="width:' + r[i].actualWidth + ';">' + r[i].innerHTML + '</span>';
}
}

function fixTableWidth(tbl){
for (var i=0; i < tbl.tHead.rows.length; i++) findRowWidth(tbl.tHead.rows[i].cells);
findRowWidth(tbl.tBodies[0].rows[0].cells);
if (tbl.tFoot) for (var i=0; i < tbl.tFoot.rows.length; i++) findRowWidth(tbl.tFoot.rows[i].cells);

//tbl.width = '';

for (var i=0; i < tbl.tHead.rows.length; i++) setRowWidth(tbl.tHead.rows[i].cells);
setRowWidth(tbl.tBodies[0].rows[0].cells);
if (tbl.tFoot) for (var i=0; i < tbl.tFoot.rows.length; i++) setRowWidth(tbl.tFoot.rows[i].cells);
}

function makeScrollableTable(tbl,scrollFooter,height){
var c, pNode, hdr, ftr, wrapper, rect;

if (typeof tbl == 'string') tbl = document.getElementById(tbl);

pNode = tbl.parentNode;
fixTableWidth(tbl);

c = container.length;
container[c] = document.createElement('<SPAN style="height: 100; overflow: auto;">');
container[c].id = tbl.id + "Container";
pNode.insertBefore(container[c], tbl);
container[c].appendChild(tbl);
container[c].style.width = tbl.clientWidth + 2 * tbl.clientLeft + scrollbarWidth();



hdr = tbl.cloneNode(false);
hdr.id += 'Header';
hdr.appendChild(tbl.tHead.cloneNode(true));
tbl.tHead.style.display = 'none';

if (!scrollFooter || !tbl.tFoot){
ftr = document.createElement('<SPAN style="width:1;height:1;clip: rect(0 1 1 0);background-color:transparent;">');
ftr.id = tbl.id + 'Footer';
ftr.style.border = tbl.style.border;
ftr.style.width = getActualWidth(tbl) + 2 * tbl.clientLeft;
ftr.style.borderBottom = ftr.style.borderLeft = ftr.style.borderRight = 'none';
}else{
ftr = tbl.cloneNode(false);
ftr.id += 'Footer';
ftr.appendChild(tbl.tFoot.cloneNode(true));
ftr.style.borderTop = 'none';
tbl.tFoot.style.display = 'none';
}

wrapper = document.createElement('<table border=0 cellspacing=0 cellpadding=0>');
wrapper.id = tbl.id + 'Wrapper';
pNode.insertBefore(wrapper, container[c]);

wrapper.insertRow(0).insertCell(0).appendChild(hdr);
wrapper.insertRow(1).insertCell(0).appendChild(container[c]);
wrapper.insertRow(2).insertCell(0).appendChild(ftr);

wrapper.align = tbl.align;
tbl.align = hdr.align = ftr.align = 'left';
hdr.style.borderBottom = 'none';
tbl.style.borderTop = tbl.style.borderBottom = 'none';



// adjust page size
if (c == 0 && height == 'auto'){
onResizeAdjustTable();
onResizeHandler = window.onresize;
window.onresize = onResizeAdjustTable;
}else{
container[c].style.height = height;
}
}

function onResizeAdjustTable(){
if (onResizeHandler) onResizeHandler();

var rect = container[0].getClientRects()(0);
var h = document.body.clientHeight - (rect.top + (document.body.scrollHeight - rect.bottom));
container[0].style.height = (h > 0) ? h : 1;
}

function printPage(){
var tbs = document.getElementsByTagName('TABLE');
var e;

for (var i=0; i < container.length; i++) container[i].style.overflow = '';

window.print();

for (var i=0; i < container.length; i++) container[i].style.overflow = 'auto';
}

</script>
]]></value>
</data>

好了,這樣就可以完成了。使用該方法可以實現用戶端的排序和托拽功能,只要你找到相應的js代碼(或者自己寫)然後使用此法分析你的用戶端代碼,最後將你的DataGrid的輸出定位成你想要的結果,一切就OK了!由於時間關係該控制項分頁和滾動不能同時,希望有興趣的網友可以實現之。我在寫此文章的目的旨在拋磚引玉的作用,希望對大家的編程技術有所提高和協助。謝謝閱讀!有什麼問題或者好的建議請與我聯絡。


相關文章

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。