How to create a scroll bar in a DataGrid

Source: Internet
Author: User
Tags header insert resource wrapper
Datagrid
We must have encountered the use of the DataGrid in the development of the time because we do not want to paging (data is not so much) but not on the page, then we want to appear in the DataGrid a scroll bar, you can scroll up and down the DataGrid inside the data without scrolling up and down the page, Because the purpose of this article is to illustrate how to do so, the reader can think through the details of the problem (for example: both paging and scrolling, etc.). In order to scroll the DataGrid we need a client-side table scrolling JS script (which I downloaded from the CodeProject), but cannot scroll the table header (that is, the first line). We all know that the DataGrid will generate a table after it is explained to the client, but this table is made of <tr><td>. In our script we need to use the thead and tbody of the table (this feature is used in most client applications, such as client sorting, column drag, and so on), so our next task is how to add < to this DataGrid for our clients It's thead><tbody>. If you have an idea of the user's custom controls and the principles of the ASP.net page, we know that the control will end up being rendered (Render) on the page, so we can override this method to complete the custom rendering of the DataGrid. Listen, it's a little scary, so how does a complex control appear? Don't worry, first we create a custom control that looks like this: public class PowerDataGrid:System.Web.UI.WebControls.DataGrid
From this we can see that our controls are inherited from the DataGrid, so our current control has all the functionality of the DataGrid without having to write a line of code. Next we want to embed the JS code we prepared into our control, so that the page on which the control is put on the client will eventually have this JS code to complete our scrolling task. To do this, we'll rewrite the pre-presentation method:
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>");
}
}
In this method we have access to the resource file. Oh! Forgot to say we also have to create a resource file, to save our JS code. We first register the corresponding scrolltable data (a section of JS script) in the resource code into the client's script block. Finally we will <script>makescrollabletable (' + This.id + ', true, ' auto ') in order to be initialized;</script> Section script registration to the page load start execution (I think it should be the same as the OnLoad method in the body). Using this method is a good option when you need to load client script. Well, the client script is there, and the rest is to process our client DataGrid (that is, the client table that the DataGrid renders). In order to render our own DataGrid we need to rewrite the rendering method as shown below:
protected override void Render (HtmlTextWriter output)
{
Output. Write (This.parsemarkup ());
}
Where a parsemarkup function is invoked, and the modifier produces a script (string) of output, which is a table containing thead and tbody. Because this method is only used by the control itself, we set it to private code as follows:
private String Parsemarkup () {
Insert Thead label and TBODY label
StringWriter writer = new StringWriter ();
HtmlTextWriter buffer = new HtmlTextWriter (writer);
Base. Render (buffer);
String pmarkup = writer. ToString ();

Finding the end of the first table label is also the first > character
Pmarkup = Pmarkup.insert (Pmarkup.indexof (">") + ">". Length, "<thead>");
Wrap the first TR closed range with THEAD, and now the first <thead> has been drawn. Need to draw
It's the end of </thead> and </tbody> also find the first </tr> to insert </thead> and </tdoby>
Pmarkup = Pmarkup.insert (Pmarkup.indexof ("</tr>") + "</tr>". Length, "</thead><tbody>");
Insert a </tbody> on the front of the last </table>.
Pmarkup = Pmarkup.replace ("</table>", "</tbody></table>");
return pmarkup;
}
In this method we first instantiate a StringWriter object writer, and use the object as a parameter to instantiate a HtmlTextWriter object buffer. The key is that we call the base class render to fill the buffer with what we want to output (a stack of scripts is a table, if you can see it with a monitor). Well, the rest of the work is to analyze the script, and then we'll replace the <tr> with <thead> and <tr> after the first occurrence of <tr> in the script. Finally, we output this table to the client, which we have replaced and modified, all ok!

Note: The reason for using the StringWriter is that it can save the original characters from the buffer, such as/t/n or something. How to configure resource files: First add a resource file to your project, the name is the same as your control, and then add a section to the file
<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>

All right, so that's all we can do. Using this method can achieve the client's sort and pull function, as long as you find the corresponding JS code (or write yourself) and then use this method to analyze your client code, and finally the output of your DataGrid as you want to the results, everything OK! Because of the time relationship the control paging and scrolling cannot at the same time, hope that interested users can realize it. I am writing this article aims to stimulate the role, I hope that the programming technology for everyone to improve and help. Thanks for reading! If you have any questions or good suggestions, please contact me.


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.