Customers have an ASP.NET DATAGRID control with a scroll bar, I have to write:
Using system;
Using system.Web.ui;
Using system.Web.ui.webcontrols;
Using system.componentmodel;
Using system.diagnostics;
Using system.io;
Using system.Web.ui.design.webcontrols;
Using system.text;
Using system.drawing;
[Assembly: tagprefix ("Microsoft.gtec.dsv", "gtecdsv")]
Namespace Microsoft.gtec.dsv
{
///
/// Summary Description for WebcustomControl1.
/// summary>
[ToolboxData ("<{0}: scrollablefixedheaderdatagrid runat = server> {0}: scrollablefixedheaderdatagrid>")]
Public Class ScrollablefixedHeaderDataGrid: System.Web.ui.WebControls.DataGrid
{
Protected Override Void Render (HTMLTextWriter Output)
{
// Use this flag to determine WHETHER The Component is in design-time or runtime.
// The Control Will Be Rendered Differently In Ide.
// Don't Bother To Use DataGridDesigner.getdesigntimehtml
Bool DesignMode = ((Site! = null) && (site.designmode));
// BACKING UP THE Properties Need To change During the render process
String Templeft = style ["left"];
String Temptop = Style ["TOP"];
Unit Tempheight = Height;
String TemptableStyle = Style ["Table-Layout"];
// Render a "
Output.writebegintag ("DIV");
Output.writeAttribute ("ID", ID "_div");
Output.writeAttribute ("style",
Height: " Height "; "
// Leave 20px for the Vertical Scroll Bar,
// Assuming the end-user will not set his scroll bar to more Than 20px.
"Width:" (width.value 20) "PX;"
"TOP:" style ["TOP"] ";" "Left:" Style ["Left"] ";"
"Position:" Style ["position"] ";"
"OVERFLOW-X: Auto;"
"Z-index:" style ["z-index"] ";"
// Render The Scrollbar Differently for Design-Time and Runtime.
"OVERFLOW-Y:" (DesignMode? "Scroll": "auto")
);
Output.write (htmltextwriter.tagrightchar);
// The datagrid is inside the "
Style ["Left"] = "0px";
Style [TOP "] =" 0px ";
// render the datagrid.
Base.Render (Output);
Output.writeEndtag ("DIV");
// Restore the VALUES
STYLE ["Left"] = Templeft;
STYLE ["TOP"] = Temptop;
// The folload rendering is Only Necessary Under Runtime. It has NEGATIVE IMPACT DURING DESIGN TIME.
IF (! designmode)
{
// Render Another Copy of The DataGrid with Only Headers.
// Render It After the DataGrid with contents,
// SO That it is on the top. z-index is more intrlex here.
// set height to 0, SO That IT Will Adjust On ITS OWN.
Height = New Unit ("0px");
StringWriter SW = new stringwriter ();
HTMLTextWriter HTW = New HtmlTextWriter (SW);
// this style is important for matching column widths later.
Style [Table-Layout "] =" fixed ";
Base.render (htw);
Stringbuilder sbrenderedtable = sw.getstringbuilder ();
HTW.CLOSE ();
SW.CLOSE ();
Debug.assert ((sbrenderedtable.length> 0),
"Rendered HTML String is Empty. Check ViewState Usage and Database");
String Temp = sbrenderedtable.toString ();
IF (sbrenderedtable.length> 0) {
// allowpaging at the top?
IF & ((anyposition.top == Pagerstyle.position ||))))))))))))
{
Trace.writeline (TEMP);
SBRENDEREDTABLE.REPLACE (ID, ID "_PAGER", 0, (Temp.IndexOf (ID) id.length));
Temp = sbrenderedtable.toString ();
String Pager = Temp.Substring (0, Temp.tolower (). Indexof (@ "< TR>") 5);
Trace.writeLine (PAGER);
Output.write (PAGER);
Output.writeEndtag ("Table");
// Start of Pager's
INT Start = Temp.tolower (). Indexof (@ "
// end of pager's tr>
INT end = Temp.tolower (). Indexof (@ " tr>") 5;
// remove the
SbrenderedTable.Remove (start, end-start);
Trace.writeline (sbrenderedtable.toString ());
SBRENDEREDTABLE.REPLACE (ID "_pager", ID "_headers", 0, (Temp.indexof (ID "_ Pager") (ID "_ Pager"). LENGTH)
Temp = sbrenderedtable.toString ();
String TableHeaders = Temp.Substring (0, (Temp.tolower ()). IndexOf (@ " TR>") 5);
TRACE.WRITELINE (TABLEHEADERS);
Output.write (TableHeaders);
Output.writeEndtag ("Table");
String headerid = ID "_headers";
String PagerID = ID "_pager";
String DiVid = ID "_div";
String AdjustWidthscript = @ "
// debugger;
Var headertableRow = " Headerid @". Rows [0];
Var OriginalTableRow = " ID @". Rows [1]; "
// Adjust header row's heiGHT. @ "
Headertablerow.height = OriginalTableRow.offsetheight;
"
// Adjust Pager Row's Height, Width.
PagerID @ ". Rows [0] .height =" id @ ". Rows [0] .offsetheight;
"
PAGERID @ ". style.width =" id @ ". OffsetWidth;
For (var i = 0; i HeadertableRow.cells [i] .width = OriginalTableRow.cells [i] .offsetwidth; } " // also needs to adjut the width of the " // Since The Table's Actual Width Can Go Beyond The Width Specified At Server Side Under Edit Mode. // The Server Side Width Manipulation is Mainly for Design-Time APPEARANCE. Divid @ ". style.width =" id @ ". OffsetWidth 20 'PX'; " // The folload script is for flow-layout. We cannot get the position of the control // ON Server Side if the the the page is with flow-layout. Headerid @ ". style.Left =" DIVID @ ". Offsetleft; " Headerid @ ". style.top =" divid @ ". Offsettop " PagerID @ ". OFFSetHeight; " HeaderID @ ". style.position = 'absolute'; " PAGERID @ ". style.left =" DIVID @ ". Offsetleft; " PagerID @ ". style.top =" DIVID @ ". Offsettop; " PAGERID @ ". style.position = 'absolute'; script> Page.RegisterStartupScript ("DummyKey" this.id, AdjustWidthscript; // output.write (AdjustWidthscript); } Else { // Replace The Table's ID with a new id. // it is tricky what we must only replace the 1st Occurence, // Since The Rest Occurences Can Be Used for Postback Scripts for Sorting. SBRENDEREDTABLE.REPLACE (ID, ID "_Headers", 0, (Temp.IndexOf (ID) id.length)); Trace.writeline (sbrenderedtable.toString ()); // We Only Need The Headers, Stripping The Rest Contents. Temp = sbrenderedtable.toString (); String TableHeaders = Temp.Substring (0, (Temp.tolower ()). IndexOf (@ " TR>") 5); TRACE.WRITELINE (TABLEHEADERS); Output.write (TableHeaders); Output.writeEndtag ("Table"); // Client Side Script for Matching Column Widths. . String AdjustWidthscript = @ " // debugger; Var headertableRow = " this.id @" _Headers.Rows [0]; Var OriginalTableRow = " this.id @". Rows [0]; Headertablerow.height = OriginalTableRow.offsetheight; For (var i = 0; i HeadertableRow.cells [i] .width = OriginalTableRow.cells [i] .offsetwidth; } " // also needs to adjut the width of the " // Since The Table's Actual Width Can Go Beyond The Width Specified At Server Side Under Edit Mode. // The Server Side Width Manipulation is Mainly for Design-Time APPEARANCE. THIS.ID "_div" @ ". style.width =" this.id @ ". OffsetWidth 20 'PX';" // The folload script is for flow-layout. We cannot get the position of the control // ON Server Side if the the the page is with flow-layout. THIS.ID "_Headers" @ ". style.left =" this.id @ "_ Div.Offsetleft; " THIS.ID "_Headers" @ ". style.top =" this.id @ "_ Div.OffSettop; " THIS.ID "_Headers" @ ". style.position = 'Absolute'; script> Page.RegisterStartupScript ("DummyKey" this.id, AdjustWidthscript; //output.write(AdjustWidthscript); } Height = Tempheight; Style [Table-Layout "] = TemptableStyle; } } } Protected Override Void OnNit (Eventargs E) { IF (0 == width.Value) width = new unit ("400px"); IF (0 == Heart.Value) Height = New Unit ("200px"); // Transparent header is not allows. IF (Headerstyle.Backcolor.Isempty) { Headerstyle.backcolor = color.white; } // transparent facer is not allowed. IF (PagerstyLle.backColor.isempty) { Pagersty.backcolor = color.white; } Base.onit (E); } [Browsable (false)] Public Override Bool Showheader { get { Return True; } set { IF (false == value) "" "User The Original DataGrid To Set Showheaders to False."); } } } }