|
|
Comments and Discussions
|
|
 |

|
Hi,
I'm currently using your scroll grid in my project. But when i tried to put it inside content template or iframe, the items didn't matched/aligned to its header.
Please help..
Thanks,
Eee
|
|
|
|

|
Hi,
I added the ScrollingGrid.dll as reference to my project and the ScrollingGrid.js in the work.
But an error ocurrs in the js while trying to get the div called "divContent".
I searched it on the demo page html source, and it was there. But in my page, I can't find it.
This DIV should be created by the component or a must create it manually? here is my implementation:
<avg:ScrollingGrid ID="sg1" runat="server" Width="450" Height="130" HeaderWidthReduction="17" BorderColor="Red" ScrollingEnabled="true">
<asp:GridView ID="GvBusca" runat="server" AutoGenerateColumns="false" Width="600px">
<HeaderStyle CssClass="tableHead1" />
<RowStyle CssClass="linhaListagem1" />
<AlternatingRowStyle CssClass="linhaListagem2" />
<EmptyDataRowStyle CssClass="linhaListagem2" />
<Columns>
<asp:BoundField DataField="CD_ESPECIE" ItemStyle-HorizontalAlign="Left" HeaderText="Espécie">
<ItemStyle Wrap="false" />
<HeaderStyle Wrap="false" />
</asp:BoundField></asp:DataGrid>
</avg:ScrollingGrid><
|
|
|
|

|
I found out the problem.
The problem is that this component works only with DataGrid.
I was trying with GridView.
Is there a version of this component working with GridView?
Thanks
|
|
|
|
|

|
Hi,
This article is somuch helpful..here I want to freeze the one column of datagrid while horizontal scrolling....Can any one suggest the solution...
Thanking you...
|
|
|
|

|
This article is awesome.I tried somany options but I failed in cross browser support.Here I got solution exactly.
modified on Sunday, November 7, 2010 11:42 PM
|
|
|
|

|
Ashley,
Thanks for sharing this code, I have a requirement to change the header label or different conditions, so I use the OnItemDataBound event to change the Header labels, the Header labels do get changed but the Fixed Header property doesn't work. I using the DataGrid inside and UpdatePanel.
Do you have any work around or solution for this.
This is ScrollingGrid code snippet
<avg:ScrollingGrid ID="ScrollDGSource" runat="server" BorderWidth="1" BorderColor="SlateGray"
ScriptPath="../../Javascript/" Height="100px" Width="215px">
<asp:DataGrid ID="gridSource" runat="server" SkinID="None" AutoGenerateColumns="False" AllowSorting="False" Width="205px" OnItemDataBound="OnSourceGridItemDataBound" >
<HeaderStyle HorizontalAlign="Center" BackColor="#F6DFE4" Font-Bold="true" ForeColor="Black" />
<Columns>
<asp:TemplateColumn>
<HeaderTemplate>
<asp:CheckBox ID="chkItemHeader" runat="server" />
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="chkItem" runat="server" />
</ItemTemplate>
</asp:TemplateColumn>
<asp:BoundColumn HeaderText="J#" DataField = "JNoCtrlLot" ItemStyle-HorizontalAlign="center" ItemStyle-Wrap="False" ItemStyle-Width="80px"/>
<asp:BoundColumn HeaderText="Analyser" DataField = "AnalyserTypeCtrlNo" ItemStyle-HorizontalAlign="center" ItemStyle-Wrap="False" ItemStyle-Width="60px"/>
</Columns>
</asp:DataGrid>
</avg:ScrollingGrid>
This is my OnItemDataBound
protected void OnSourceGridItemDataBound(object sender, DataGridItemEventArgs e)
{
if(e.Item.ItemType == ListItemType.Header) // || (e.Item.ItemType == ListItemType.AlternatingItem))
{
if (rbMultiJNo.Checked == true)
{
e.Item.Cells[1].Text = "J#";
e.Item.Cells[2].Text = "Analyser";
}
else if (rbMultiControlNo.Checked == true)
{
e.Item.Cells[1].Text = "Control Lot";
e.Item.Cells[2].Text = "Control #";
}
}
}
}
modified on Thursday, October 7, 2010 4:37 PM
|
|
|
|
|

|
Just following up on the post back in '08 from Jocke
"Hi,
Great control!
I have one problem though:
When I am adding an UpdatePanel on the page the control starts to behave a bit strange.
I have paging and sorting set to true on the grid and when I click on either sorting or paging buttons, the footer is moved back into the grid again. I still want it outside the scrolling area.
Can I not use Ajax with this control? I really would like to...
Thanks in advance for your help!
Jocke"
Has anyone found a solution to this?
Any help is much appreciated. Thank You.
Mike
|
|
|
|

|
Hi,
I think I have get the key to solove the problem.
It's cause by updatepanel, if you use a inline javascript in updatepanel, they will think the content had been build in client and escape to run javascript in client again ,even you put them into a dom object.
the solution is use ScriptManager's RegisterScriptBlock function, ajax will do javascript again
Here is code , I just modify Ashley van Gerven's code a little at OnInit event:
/// <summary>
/// Adds the necessary HTML before and after it's DataGrid child control
/// </summary>
/// <param name="e"></param>
protected override void OnInit(EventArgs e)
{
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "ScrollingGrid_js", "<script language=JavaScript src=" + ScriptPath + "ScrollingGrid.js></script>");
// find the DataGrid control
foreach (Control c in this.Controls)
{
if (c is GridView)
{
grid = (GridView)c;
break;
}
}
if (grid != null && ScrollingEnabled)
{
if (FirefoxBorderWorkaround)
{
// for best results in Firefox set these properties on the DataGrid
grid.GridLines = GridLines.None;
grid.BorderWidth = 0;
}
StringBuilder html = new StringBuilder();
if (grid.ShowHeader)
{
string divHdrStyle = "overflow:hidden;";
if (HeaderWidthReduction > 0)
divHdrStyle += string.Format("margin-right:{0}px;", HeaderWidthReduction);
// header div
html.AppendFormat("<div id={0}$divHdr style='{1}'>\r\n", this.ClientID, divHdrStyle);
// header table borders
string border = "0";
string style = " style='border-collapse:collapse;'";
if (!grid.BorderWidth.IsEmpty)
border = grid.BorderWidth.Value.ToString();
else if (grid.GridLines == GridLines.Both)
border = "1";
if (grid.CellSpacing > 0) // FF doesn't display cellspacing correctly with border-collapse style
style = "";
string borderColor = "";
if (!grid.BorderColor.IsEmpty)
{
string colorValue = grid.BorderColor.Name;
if (colorValue.StartsWith("ff"))
colorValue = "#" + colorValue.Substring(2);
borderColor = " borderColor='" + colorValue + "'";
}
// container table + header table
if (grid.CellPadding == -1)
grid.CellPadding = 2;
string cellpadding = string.Format("cellpadding='{0}'", grid.CellPadding);
html.AppendFormat("<table cellpadding=0 cellspacing=0 id={3}$headerCntr><tr><td><table id={3}$tblHdr border='{0}' {1} cellspacing='{2}' {4}{5}>", border, cellpadding, grid.CellSpacing, this.ClientID, borderColor, style);
html.Append(" <tr></tr></table></td></tr></table>\r\n");
//close header div
html.Append("</div>\r\n");
}
// scrolling div + 2nd container table
html.AppendFormat("<div id={3}$divContent style='height:{1};overflow:{2};' onscroll='updateScroll(this, \"{3}\")'><table cellpadding=0 cellspacing=0 id={3}$contentCntr><tr><td>", Width, Height, this.Overflow, this.ClientID);
// insert our html as the first control
this.Controls.AddAt(0, new LiteralControl(html.ToString()));
// close container table & scrolling div (appended to end)
string appendHtml = "";
if (grid.ShowHeader)
appendHtml += "</td></tr></table>\r\n";
appendHtml += "</div>\r\n";
// hidden input for scroll position
appendHtml += string.Format("<input type=hidden name={0}$hdnScrollPos id={0}$hdnScrollPos>\r\n", this.ClientID);
this.Controls.Add(new LiteralControl(appendHtml));
// check for datagrid pager
bool lastRowIsPager = false;
if (grid.AllowPaging && grid.PagerSettings.Visible && (grid.PagerSettings.Position == PagerPosition.Bottom || grid.PagerSettings.Position == PagerPosition.TopAndBottom))
{
lastRowIsPager = true;
// pager table underneath scrolling grid
string tblPagerStyle = "width:100%;";
if (FooterWidthReduction > 0)
tblPagerStyle += string.Format("margin-right:{0}px;", FooterWidthReduction);
this.Controls.Add(new LiteralControl(string.Format("<table id={0}$tblPager cellpadding={1} cellspacing={2} style='{3}'> <tr></tr></table>\r\n", this.ClientID, grid.CellPadding, grid.CellSpacing, tblPagerStyle)));
}
// javacript to initialise grid
if (grid.ShowHeader)
{
string script = string.Format("<script language=javascript name="+Guid.NewGuid()+">\r\n<!--\r\n setTimeout(\"initScrollingGrid('{0}', '{1}', {2})\", 50) \r\n//--></script>", this.ClientID, grid.ClientID, lastRowIsPager.ToString().ToLower());
ScriptManager sm = ScriptManager.GetCurrent(Page);
if (sm != null && sm.IsInAsyncPostBack)
{
script = string.Format("setTimeout(\"initScrollingGrid('{0}', '{1}', {2})\", 50);", this.ClientID, grid.ClientID, lastRowIsPager.ToString().ToLower());
ScriptManager.RegisterClientScriptBlock(this, typeof(Page), "scrolling grid script"+this.ClientID, script, true);
}
else
{
this.Controls.Add(new LiteralControl(script));
}
}
}
this.Load += new EventHandler(ScrollingGrid_Load);
base.OnInit(e);
}
Hope can help you!
And Ashley van Gerven, it's great work,thanks a lot for your project, it's very useful,haha
|
|
|
|

|
Hello,
I've used your control on a first project developped with Framework 2.0 and it works fine.
Now I want to use it in a project with Framework 3.5. The scrolling works but the header isn't fix and i don't understand why. The grid is in a page which is herited a Masterpage.
Does anyone experience the same problem ?
Thanks for your help.
Nicolas
|
|
|
|

|
I'm new to Web Development, so I need a little help creating my tool at work.
I'm having some troubles trying to load the source project in either VS2003 or VS2008. VS2008 will try and convert it, claims it was successful, then when loading the environment unloads the ScrollingGrid files.
VS2003 reports that it cannot open because there is "no Web Server detected at URL:'http://Localhost:/_dev/ScrollingGrid'.
Anyone have any ideas?
Thanks in advance for any help.
|
|
|
|

|
Just a follow up.
I'm not sure why I couldn't load it, but I found a work around by just creating a new project and then importing all the files to create the new GridView DLL version.
But now I cannot get the header or pager to freeze in VS2008 ASP.NET 3.5? Has anyone else experienced this?
|
|
|
|

|
Trying to get this to work with a gridview. Copied code posted that was indicated to work with gridview, but I have NO ScrollBars and the Header does not freeze. Could you indicate specifically which lines would need to change in ScrollingGrid.js. Thank you in advance for your assistance.
|
|
|
|

|
I have few textboxes and dropdown lists on my page and a search button. After filling textboxes and selecting values in dropdown, I click Search button and on click, Datagrid with scrollingGrid control is displayed. See sample code below.
<tr>
<td align="left">
<cc1:ScrollingGrid ID="divFreightRate1" Visible="false" Width="100%" Height="150px"
ScrollBars="Auto" runat="server">
<asp:DataGrid ID="dgOceanFreightRate" runat="server" AllowPaging="True" AutoGenerateColumns="False"
PagerStyle-HorizontalAlign="Left" OnPageIndexChanged="dgOceanFreightRate_PageIndexChanged"
PagerStyle-Mode="NextPrev" PagerStyle-NextPageText="Next" PagerStyle-Position="Bottom"
Font-Size="8pt" HeaderStyle-ForeColor="white" PagerStyle-PrevPageText="Prev"
PageSize="20" CellSpacing="1" GridLines="None">
<Columns>
<asp:TemplateColumn>
<HeaderTemplate>
<input disabled="disabled" type="checkbox" /></HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="chkItem" runat="server" />
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="S.No." HeaderStyle-Font-Bold="true" HeaderStyle-HorizontalAlign="Center">
<ItemStyle HorizontalAlign="left" />
<ItemTemplate>
<%# (dgOceanFreightRate.PageSize * dgOceanFreightRate.CurrentPageIndex) + Container.ItemIndex + 1%>
</ItemTemplate>
</asp:TemplateColumn>
...20 more columns here...
</Columns>
<HeaderStyle CssClass="head_bg_crm" />
<AlternatingItemStyle CssClass="grid_bg" />
<PagerStyle HorizontalAlign="Left" NextPageText="Next" Position="Bottom" PrevPageText="Prev" />
</asp:DataGrid>
</cc1:ScrollingGrid>
It shows javascript error message and data is not displayed properly in Grid. but when I refresh the page, it works fine, no error.
I have enabled script debugging to see the exact javascript error mentioned in the subject line.
Strange behavior: Scrolling Grid works fine at my local machine, issue occurs at test and production server. My local machine is windows XP and server machine is windows 2003 server, standard edition.
Please reply ASAP.
|
|
|
|

|
Hello
Thanks man, for a such good article and code.
It helped me in my requirement.
Ones again thanks .......
bye tc
Avinash Patil
avinashpatil3484@gmail.com
|
|
|
|

|
Can someone please tell me how to avoid the horizontal scroll bar in this control? I want to show only the vertical scroll for the data grid in my web page. Please help.
|
|
|
|

|
This is a very nice article. Is there a sample of this in VB code ?
Thanx,
Herman
|
|
|
|

|
Anyone encounter this when apply this code to gridview. An extra row is appended to the bottom of the grid.
|
|
|
|

|
Solved the problem by removing the footer because it wasn't working.
|
|
|
|

|
I converted ScrollingGrid to use a GridView. This works ok. I have a GridView where I am using the built in Paging. The Paging is set for Top. Because the pager is at the top (it's the first row in the table), the ScrollingGrid thinks this is the header and freezes it and my real header is not frozen.
Has anyone created a work around for this?
I do not want to go and have to rework my gridviews to use a separate paging component and change more code.
Thanks,
Rich
|
|
|
|

|
the grid working very well, Please help us to convert it that works on asp.net gridview
modified on Friday, December 19, 2008 12:50 AM
|
|
|
|

|
I have it working with a GridView. It was very easy to convert, but here is my source code. Just update ScrollingGrid.cs Rich
/* * Copyright © 2005, Ashley van Gerven (ashley.vg@gmail.com) * All rights reserved. * * Use in source and binary forms, with or without modification, is permitted * provided that the above copyright notice and disclaimer below is not removed. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * * http://www.codeproject.com/KB/webforms/ScrollingGrid.aspx */
using System; using System.Drawing; using System.IO; using System.Text; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.ComponentModel;
namespace AvgControls { /// <summary> /// Cross-browser container control for a DataGrid to freeze it's header and bottom pager while scrolling both horizontally and vertically. /// </summary> [ToolboxData("<{0}:ScrollingGrid runat=server></{0}:ScrollingGrid>")] [ToolboxBitmap(typeof(ScrollingGrid), "ScrollingGridIcon.bmp")] public class ScrollingGrid : Panel { private GridView grid = null;
/// <summary> /// Content DIV overflow style setting. Can be: auto, scroll, hidden /// </summary> public string Overflow = "scroll"; /// <summary> /// Get/set pixel width to reduce the header by - e.g. 17 = scrollbar width (if you don't want the header to extend accross the top of the scrollbar) /// </summary> public int HeaderWidthReduction = 0; /// <summary> /// Get/set pixel width to reduce the footer by /// </summary> public int FooterWidthReduction = 0; /// <summary> /// Set to false to display the DataGrid as normal (i.e. without any scrolling or frozen header etc.) /// </summary> public bool ScrollingEnabled = true; /// <summary> /// Get/set the start scroll position of the content DIV /// </summary> public Point StartScrollPos = new Point(0, 0); /// <summary> /// Get/set the location of ScrollingGrid.js /// </summary> public string ScriptPath = ""; /// <summary> /// Set to false if GridLines & BorderWidth properties on DataGrid should not be set for optimal results in Firefox /// </summary> public bool FirefoxBorderWorkaround = true;
/// <summary> /// Constructor /// </summary> public ScrollingGrid() { // Initialise width & height this.Width = 450; this.Height = 200; }
/// <summary> /// Adds the necessary HTML before and after it's DataGrid child control /// </summary> /// <param name="e"></param> protected override void OnInit(EventArgs e) { Page.ClientScript.RegisterClientScriptBlock(this.GetType(),"ScrollingGrid_js", "<script language=JavaScript src=" + ScriptPath + "ScrollingGrid.js></script>"); // find the DataGrid control foreach (Control c in this.Controls) { if (c is GridView) { grid = (GridView)c; break; } } if (grid != null && ScrollingEnabled) { if (FirefoxBorderWorkaround) { // for best results in Firefox set these properties on the DataGrid grid.GridLines = GridLines.None; grid.BorderWidth = 0; }
StringBuilder html = new StringBuilder(); if (grid.ShowHeader) { string divHdrStyle = "overflow:hidden;"; if (HeaderWidthReduction > 0) divHdrStyle += string.Format("margin-right:{0}px;", HeaderWidthReduction); // header div html.AppendFormat("<div id={0}$divHdr style='{1}'>\r\n", this.ClientID, divHdrStyle); // header table borders string border = "0"; string style = " style='border-collapse:collapse;'"; if (!grid.BorderWidth.IsEmpty) border = grid.BorderWidth.Value.ToString(); else if (grid.GridLines == GridLines.Both) border = "1"; if (grid.CellSpacing > 0) // FF doesn't display cellspacing correctly with border-collapse style style = ""; string borderColor = ""; if (!grid.BorderColor.IsEmpty) { string colorValue = grid.BorderColor.Name; if (colorValue.StartsWith("ff")) colorValue = "#" + colorValue.Substring(2); borderColor = " borderColor='" + colorValue + "'"; } // container table + header table if (grid.CellPadding == -1) grid.CellPadding = 2; string cellpadding = string.Format("cellpadding='{0}'", grid.CellPadding); html.AppendFormat("<table cellpadding=0 cellspacing=0 id={3}$headerCntr><tr><td><table id={3}$tblHdr border='{0}' {1} cellspacing='{2}' {4}{5}>", border, cellpadding, grid.CellSpacing, this.ClientID, borderColor, style ); html.Append(" <tr></tr></table></td></tr></table>\r\n"); //close header div html.Append("</div>\r\n"); }
// scrolling div + 2nd container table html.AppendFormat("<div id={3}$divContent style='height:{1};overflow:{2};' onscroll='updateScroll(this, \"{3}\")'><table cellpadding=0 cellspacing=0 id={3}$contentCntr><tr><td>", Width, Height, this.Overflow, this.ClientID);
// insert our html as the first control this.Controls.AddAt(0, new LiteralControl(html.ToString()));
// close container table & scrolling div (appended to end) string appendHtml = ""; if (grid.ShowHeader) appendHtml += "</td></tr></table>\r\n"; appendHtml += "</div>\r\n";
// hidden input for scroll position appendHtml += string.Format("<input type=hidden name={0}$hdnScrollPos id={0}$hdnScrollPos>\r\n", this.ClientID);
this.Controls.Add(new LiteralControl(appendHtml));
// check for datagrid pager bool lastRowIsPager = false; if (grid.AllowPaging && grid.PagerSettings.Visible && (grid.PagerSettings.Position == PagerPosition.Bottom || grid.PagerSettings.Position == PagerPosition.TopAndBottom)) { lastRowIsPager = true; // pager table underneath scrolling grid string tblPagerStyle = "width:100%;"; if (FooterWidthReduction > 0) tblPagerStyle += string.Format("margin-right:{0}px;", FooterWidthReduction); this.Controls.Add(new LiteralControl( string.Format("<table id={0}$tblPager cellpadding={1} cellspacing={2} style='{3}'> <tr></tr></table>\r\n", this.ClientID, grid.CellPadding, grid.CellSpacing, tblPagerStyle) )); } // javacript to initialise grid if (grid.ShowHeader) this.Controls.Add( new LiteralControl(string.Format("<script language=javascript>\r\n<!--\r\n setTimeout(\"initScrollingGrid('{0}', '{1}', {2})\", 50) \r\n//--></script>", this.ClientID, grid.ClientID, lastRowIsPager.ToString().ToLower())) ); } this.Load += new EventHandler(ScrollingGrid_Load); base.OnInit(e); }
/// <summary> /// Outputs start of control's container TABLE /// </summary> /// <param name="writer"></param> public override void RenderBeginTag(HtmlTextWriter writer) { // bg color style string style = ""; if (!this.BackColor.IsEmpty) { string colorValue = this.BackColor.Name; if (colorValue.StartsWith("ff")) colorValue = "#" + colorValue.Substring(2); style = string.Format("background-color:{0};", colorValue); } if (ScrollingEnabled) style += string.Format("width:{0};", this.Width); string html = string.Format("<table id={0} name=ScrollingGrid style='{1} table-layout:fixed' cellpadding=0 cellspacing=0 border=0", this.ClientID, style); if (this.CssClass != null && this.CssClass.Length > 0) html += string.Format(" class='{0}'", this.CssClass); html += "><tr><td>\r\n"; writer.Write(html); }
/// <summary> /// Outputs end of control's container TABLE /// </summary> /// <param name="writer"></param> public override void RenderEndTag(HtmlTextWriter writer) { writer.Write("</td></tr></table>\r\n"); }
/// <summary> /// Set starting scroll position of content DIV from postback /// </summary> public void SetStartScrollPosFromPostack() { string key = this.ClientID + "$hdnScrollPos"; if (HttpContext.Current.Request.Form[key] != null && HttpContext.Current.Request.Form[key].Length > 0) { string[] parts = HttpContext.Current.Request.Form[key].Split('-'); this.Controls.Add( new LiteralControl(string.Format("<script language=javascript>\r\n<!--\r\n setTimeout(\"setContentScrollPos('{0}', {1}, {2})\", 100) \r\n//--></script>", this.ClientID, parts[0], parts[1])) ); } }
/// <summary> /// Control's Load event handler /// </summary> private void ScrollingGrid_Load(object sender, EventArgs e) { // add JS to set the starting scroll position if (this.StartScrollPos.X > 0 || this.StartScrollPos.Y > 0) this.Controls.Add( new LiteralControl(string.Format("<script language=javascript>\r\n<!--\r\n setTimeout(\"setContentScrollPos('{0}', {1}, {2})\", 100) \r\n//--></script>", this.ClientID, this.StartScrollPos.X, this.StartScrollPos.Y)) ); } } }
|
|
|
|

|
Hi all,
I' downloaded the project, and tested it.
It works very well, but the fact is that the project is based on a Datagrid sollution.
I need it to work with Gridview.
Can someone help me?
Thnx,
Kauey
|
|
|
|

|
I have it working with a GridView. It was very easy to convert, but here is my source code. Just update ScrollingGrid.cs Rich
/* * Copyright © 2005, Ashley van Gerven (ashley.vg@gmail.com) * All rights reserved. * * Use in source and binary forms, with or without modification, is permitted * provided that the above copyright notice and disclaimer below is not removed. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * * http://www.codeproject.com/KB/webforms/ScrollingGrid.aspx */
using System; using System.Drawing; using System.IO; using System.Text; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.ComponentModel;
namespace AvgControls { /// <summary> /// Cross-browser container control for a DataGrid to freeze it's header and bottom pager while scrolling both horizontally and vertically. /// </summary> [ToolboxData("<{0}:ScrollingGrid runat=server></{0}:ScrollingGrid>")] [ToolboxBitmap(typeof(ScrollingGrid), "ScrollingGridIcon.bmp")] public class ScrollingGrid : Panel { private GridView grid = null;
/// <summary> /// Content DIV overflow style setting. Can be: auto, scroll, hidden /// </summary> public string Overflow = "scroll"; /// <summary> /// Get/set pixel width to reduce the header by - e.g. 17 = scrollbar width (if you don't want the header to extend accross the top of the scrollbar) /// </summary> public int HeaderWidthReduction = 0; /// <summary> /// Get/set pixel width to reduce the footer by /// </summary> public int FooterWidthReduction = 0; /// <summary> /// Set to false to display the DataGrid as normal (i.e. without any scrolling or frozen header etc.) /// </summary> public bool ScrollingEnabled = true; /// <summary> /// Get/set the start scroll position of the content DIV /// </summary> public Point StartScrollPos = new Point(0, 0); /// <summary> /// Get/set the location of ScrollingGrid.js /// </summary> public string ScriptPath = ""; /// <summary> /// Set to false if GridLines & BorderWidth properties on DataGrid should not be set for optimal results in Firefox /// </summary> public bool FirefoxBorderWorkaround = true;
/// <summary> /// Constructor /// </summary> public ScrollingGrid() { // Initialise width & height this.Width = 450; this.Height = 200; }
/// <summary> /// Adds the necessary HTML before and after it's DataGrid child control /// </summary> /// <param name="e"></param> protected override void OnInit(EventArgs e) { Page.ClientScript.RegisterClientScriptBlock(this.GetType(),"ScrollingGrid_js", "<script language=JavaScript src=" + ScriptPath + "ScrollingGrid.js></script>"); // find the DataGrid control foreach (Control c in this.Controls) { if (c is GridView) { grid = (GridView)c; break; } } if (grid != null && ScrollingEnabled) { if (FirefoxBorderWorkaround) { // for best results in Firefox set these properties on the DataGrid grid.GridLines = GridLines.None; grid.BorderWidth = 0; }
StringBuilder html = new StringBuilder(); if (grid.ShowHeader) { string divHdrStyle = "overflow:hidden;"; if (HeaderWidthReduction > 0) divHdrStyle += string.Format("margin-right:{0}px;", HeaderWidthReduction); // header div html.AppendFormat("<div id={0}$divHdr style='{1}'>\r\n", this.ClientID, divHdrStyle); // header table borders string border = "0"; string style = " style='border-collapse:collapse;'"; if (!grid.BorderWidth.IsEmpty) border = grid.BorderWidth.Value.ToString(); else if (grid.GridLines == GridLines.Both) border = "1"; if (grid.CellSpacing > 0) // FF doesn't display cellspacing correctly with border-collapse style style = ""; string borderColor = ""; if (!grid.BorderColor.IsEmpty) { string colorValue = grid.BorderColor.Name; if (colorValue.StartsWith("ff")) colorValue = "#" + colorValue.Substring(2); borderColor = " borderColor='" + colorValue + "'"; } // container table + header table if (grid.CellPadding == -1) grid.CellPadding = 2; string cellpadding = string.Format("cellpadding='{0}'", grid.CellPadding); html.AppendFormat("<table cellpadding=0 cellspacing=0 id={3}$headerCntr><tr><td><table id={3}$tblHdr border='{0}' {1} cellspacing='{2}' {4}{5}>", border, cellpadding, grid.CellSpacing, this.ClientID, borderColor, style ); html.Append(" <tr></tr></table></td></tr></table>\r\n"); //close header div html.Append("</div>\r\n"); }
// scrolling div + 2nd container table html.AppendFormat("<div id={3}$divContent style='height:{1};overflow:{2};' onscroll='updateScroll(this, \"{3}\")'><table cellpadding=0 cellspacing=0 id={3}$contentCntr><tr><td>", Width, Height, this.Overflow, this.ClientID);
// insert our html as the first control this.Controls.AddAt(0, new LiteralControl(html.ToString()));
// close container table & scrolling div (appended to end) string appendHtml = ""; if (grid.ShowHeader) appendHtml += "</td></tr></table>\r\n"; appendHtml += "</div>\r\n";
// hidden input for scroll position appendHtml += string.Format("<input type=hidden name={0}$hdnScrollPos id={0}$hdnScrollPos>\r\n", this.ClientID);
this.Controls.Add(new LiteralControl(appendHtml));
// check for datagrid pager bool lastRowIsPager = false; if (grid.AllowPaging && grid.PagerSettings.Visible && (grid.PagerSettings.Position == PagerPosition.Bottom || grid.PagerSettings.Position == PagerPosition.TopAndBottom)) { lastRowIsPager = true; // pager table underneath scrolling grid string tblPagerStyle = "width:100%;"; if (FooterWidthReduction > 0) tblPagerStyle += string.Format("margin-right:{0}px;", FooterWidthReduction); this.Controls.Add(new LiteralControl( string.Format("<table id={0}$tblPager cellpadding={1} cellspacing={2} style='{3}'> <tr></tr></table>\r\n", this.ClientID, grid.CellPadding, grid.CellSpacing, tblPagerStyle) )); } // javacript to initialise grid if (grid.ShowHeader) this.Controls.Add( new LiteralControl(string.Format("<script language=javascript>\r\n<!--\r\n setTimeout(\"initScrollingGrid('{0}', '{1}', {2})\", 50) \r\n//--></script>", this.ClientID, grid.ClientID, lastRowIsPager.ToString().ToLower())) ); } this.Load += new EventHandler(ScrollingGrid_Load); base.OnInit(e); }
/// <summary> /// Outputs start of control's container TABLE /// </summary> /// <param name="writer"></param> public override void RenderBeginTag(HtmlTextWriter writer) { // bg color style string style = ""; if (!this.BackColor.IsEmpty) { string colorValue = this.BackColor.Name; if (colorValue.StartsWith("ff")) colorValue = "#" + colorValue.Substring(2); style = string.Format("background-color:{0};", colorValue); } if (ScrollingEnabled) style += string.Format("width:{0};", this.Width); string html = string.Format("<table id={0} name=ScrollingGrid style='{1} table-layout:fixed' cellpadding=0 cellspacing=0 border=0", this.ClientID, style); if (this.CssClass != null && this.CssClass.Length > 0) html += string.Format(" class='{0}'", this.CssClass); html += "><tr><td>\r\n"; writer.Write(html); }
/// <summary> /// Outputs end of control's container TABLE /// </summary> /// <param name="writer"></param> public override void RenderEndTag(HtmlTextWriter writer) { writer.Write("</td></tr></table>\r\n"); }
/// <summary> /// Set starting scroll position of content DIV from postback /// </summary> public void SetStartScrollPosFromPostack() { string key = this.ClientID + "$hdnScrollPos"; if (HttpContext.Current.Request.Form[key] != null && HttpContext.Current.Request.Form[key].Length > 0) { string[] parts = HttpContext.Current.Request.Form[key].Split('-'); this.Controls.Add( new LiteralControl(string.Format("<script language=javascript>\r\n<!--\r\n setTimeout(\"setContentScrollPos('{0}', {1}, {2})\", 100) \r\n//--></script>", this.ClientID, parts[0], parts[1])) ); } }
/// <summary> /// Control's Load event handler /// </summary> private void ScrollingGrid_Load(object sender, EventArgs e) { // add JS to set the starting scroll position if (this.StartScrollPos.X > 0 || this.StartScrollPos.Y > 0) this.Controls.Add( new LiteralControl(string.Format("<script language=javascript>\r\n<!--\r\n setTimeout(\"setContentScrollPos('{0}', {1}, {2})\", 100) \r\n//--></script>", this.ClientID, this.StartScrollPos.X, this.StartScrollPos.Y)) ); } } }
|
|
|
|
|

|
I've been searching for a week now for a solution to this common problem, but for the gridview. I'm pretty sure this will work for it with a bit of tweaking. Thanks!!
|
|
|
|

|
I adapted your code for a Gridview control, it works ok in IE, but in Firefox the widths of the header columns are not set correctly. Is there a known solution or should I continue digging for one myself?
|
|
|
|

|
My demo using the DataGrid works with Firefox 3 but I'm not aware of a solution using the GridView I'm afraid.
"For fifty bucks I'd put my face in their soup and blow." - George Costanza
CP article: SmartPager - a Flickr-style pager control with go-to-page popup layer.
|
|
|
|

|
I changed this :
if (tdHdr.offsetWidth != widths[i])
tdHdr.style.width = widths[i] + widthAdjustment;
if (tdContent.offsetWidth != widths[i])
tdContent.style.width = widths[i] + widthAdjustment;
into this:
if (tdHdr.offsetWidth != widths[i])
tdHdr.style.width = (widths[i] + widthAdjustment) + "px";
if (tdContent.offsetWidth != widths[i])
tdContent.style.width = (widths[i] + widthAdjustment) + "px";
and it worked. Now I shall see what problems I'll hit next.
|
|
|
|

|
As I said before, I managed to set the correct widths. But it seems that this is the case just when the width of the control is bigger than the gridview's. When it is smaller, everything loads ok, but then all the widths shrink.
modified on Tuesday, November 25, 2008 4:32 AM
|
|
|
|

|
Hi,
Great control!
I have one problem though:
When I am adding an UpdatePanel on the page the control starts to behave a bit strange.
I have paging and sorting set to true on the grid and when I click on either sorting or paging buttons, the footer is moved back into the grid again. I still want it outside the scrolling area.
Can I not use Ajax with this control? I really would like to...
Thanks in advance for your help!
Jocke
|
|
|
|

|
Hi,
I have same problem with Ajax Updade Panel, someone has idea of how to this problem.
thanks,
|
|
|
|

|
I'm having the same issue, does anyone know how to get around this. Ajax has been defined in the base class so is inherited in my search page where this grid is and therefore doesn't allow the headers to be frozen. Has anyone come across a solution where they can get past this?
|
|
|
|

|
Hi,
I resolve this problem, in original code the header and pager are excluded. I change the attribute display=none in header and pager to hide and using the function clone to copy the two thus, maintaining the original.
Because when use update panel this component take the first line and last line, in original code the first time are excluded header and pager.
|
|
|
|

|
Adriano,
Could you please provide me the code u used for solving the problem. I too have the same problem please consider it as urgently.Iam waiting for your response.
Thanks
Khaliq
|
|
|
|

|
Did you ever get a response for the solution? I'm experiencing the same problem with using GridView instead of DataGrid.
|
|
|
|

|
Hi,
I have a issue with Ajax update panel. I don't see the scrollbars when I visit the page, but when I make some changes on the page and cancel changes, then the page reloads and scrollbars are visible properly.
Strange behaviour
Please help me solve this problem.
|
|
|
|

|
////code on form <script language="javascript">
function CreateNonScrollHeader(curHdrRowid,newHdrid) { var curHdrRowid=document.getElementById(curHrdRowid); var newHdrid=document.getElementById(newHdrid); copyAttributes(curHdrRowid, newHdrid); //newHdrid.innerHtml=curHdrRowId.innerHtml; for(var i=0;i<curHdrRowid.cells.length;i++) { var curHdrCell=curHdrRowid.cells.item(i); var newHdrCell=document.createElement("th"); copyAttributes(curHdrCell,newHdrCell); newHdrcell.innerHtml=curHdrCell.innerHtml; newHdrRowid.appendChild(newHdrCell); } curHdrRowid.style.display="none"; } </script>
code on code behind page protected void gvTable_PreRender(object sender, EventArgs e) { try { string jvScript = "<script language=\"javascript\">\n"; this.gvTable.HeaderRow= "tr_Header"; jvScript += "CreateNonScrollHeader(" + gvTable.HeaderRow.ClientID + "," +tr_Header.ClientID + ");\n"; jvScript += "</script>"; Page.ClientScript.RegisterStartupScript(this.GetType(), "CreateNonScrollHeader", jvScript); } catch(Exception ee) { } } error are........
1) Property or indexer 'System.Web.UI.WebControls.GridView.HeaderRow' cannot be assigned to -- it is read only 2) Cannot implicitly convert type 'string' to 'System.Web.UI.WebControls.GridViewRow' 3) The name 'tr_Header' does not exist in the current context
|
|
|
|

|
That's a very nice article and it helped me. But I am trying to display sort images when a column is sorted. It is not working for me. Do you think about it or have any solution for this? Thanks again.
Abhay Prakash Singh
|
|
|
|
|

|
Hi, I was wondering if its possible to sort the headers without postback. How can you do that? Im using the Anthem controls for AJAX implementation. thanks
|
|
|
|

|
Hi. First of all, excellent job.
Very nice control.
Width very little work I converted it so I can use it with GridView.
But I'm not being able to get it work correctly on FF2.
Can't make it scroll horizontally.
Do you know how can I make to make it work on FF?
I'm posting the generated code in case you want to check it.
Thanks!
<table id=ctl00_Main_sg1 name=ScrollingGrid style='width:600px; table-layout:fixed' cellpadding=0 cellspacing=0 border=0><tr><td>
<div id=ctl00_Main_sg1$divHdr style='overflow:hidden;margin-right:20px;'>
<table cellpadding=0 cellspacing=0 id=ctl00_Main_sg1$headerCntr><tr><td><table id=ctl00_Main_sg1$tblHdr border='0' cellpadding='0' cellspacing='0' style='border-collapse:collapse;'> <tr></tr></table></td></tr></table>
</div>
<div id=ctl00_Main_sg1$divContent style='height:275px;overflow:scroll;' onscroll='updateScroll(this, "ctl00_Main_sg1")'><table cellpadding=0 cellspacing=0 id=ctl00_Main_sg1$contentCntr><tr><td>
<div>
<table class="Grid" cellspacing="0" cellpadding="0" border="0" id="ctl00_Main_grdLotes" style="border-width:0px;border-collapse:collapse;">
<tr class="GridHeader GridTitle">
<th scope="col" style="width:40px;">Legajo</th><th scope="col" style="width:230px;">Nombre</th><th scope="col" style="width:30px;">Npi</th><th align="center" scope="col" style="width:90px;"><span>2</span></th><th align="center" scope="col" style="width:90px;"><span>7</span></th><th align="center" scope="col" style="width:90px;"><span>8</span></th><th align="center" scope="col" style="width:90px;"><span>16</span></th><th align="center" scope="col" style="width:90px;"><span>27</span></th><th align="center" scope="col" style="width:90px;"><span>40</span></th><th align="center" scope="col" style="width:90px;"><span>41</span></th><th align="center" scope="col" style="width:90px;"><span>1527</span></th><th align="center" scope="col" style="width:90px;"><span>1529</span></th><th align="center" scope="col" style="width:90px;"><span>1650</span></th><th align="center" scope="col" style="width:90px;"><span>1653</span></th><th align="center" scope="col" style="width:90px;"><span>1670</span></th>
</tr><tr class="GridField">
<td align="center" style="width:40px;">1</td><td style="width:230px;">GONZALEZ GARCIA DE ALBA, DAVID</td><td align="center" style="width:30px;">5394</td><td align="center" style="width:90px;"><input name="ctl00$Main$grdLotes$ctl02$ctl01" type="text" value="0" size="4" class="TextBox" style="width:20px;" /><span>H</span></td><td align="center" style="width:90px;"><input name="ctl00$Main$grdLotes$ctl02$ctl04" type="text" value="0" size="4" class="TextBox" style="width:20px;" /><span></span></td><td align="center" style="width:90px;"><input name="ctl00$Main$grdLotes$ctl02$ctl07" type="text" value="0" size="4" class="TextBox" style="width:20px;" /><span>I</span></td><td align="center" style="width:90px;"><input name="ctl00$Main$grdLotes$ctl02$ctl10" type="text" value="0" size="4" class="TextBox" style="width:20px;" /><span>I</span></td><td align="center" style="width:90px;"><input name="ctl00$Main$grdLotes$ctl02$ctl13" type="text" value="0" size="4" class="TextBox" style="width:20px;" /><span></span></td><td align="center" style="width:90px;"><input name="ctl00$Main$grdLotes$ctl02$ctl16" type="text" value="0" size="4" class="TextBox" style="width:20px;" /><span>D</span></td><td align="center" style="width:90px;"><input name="ctl00$Main$grdLotes$ctl02$ctl19" type="text" value="0" size="4" class="TextBox" style="width:20px;" /><span>D</span></td><td align="center" style="width:90px;"><input name="ctl00$Main$grdLotes$ctl02$ctl22" type="text" value="0" size="4" class="TextBox" style="width:20px;" /><span>I</span></td><td align="center" style="width:90px;"><input name="ctl00$Main$grdLotes$ctl02$ctl25" type="text" value="0" size="4" class="TextBox" style="width:20px;" /><span></span></td><td align="center" style="width:90px;"><input name="ctl00$Main$grdLotes$ctl02$ctl28" type="text" value="0" size="4" class="TextBox" style="width:20px;" /><span>I</span></td><td align="center" style="width:90px;"><input name="ctl00$Main$grdLotes$ctl02$ctl31" type="text" value="0" size="4" class="TextBox" style="width:20px;" /><span>I</span></td><td align="center" style="width:90px;"><input name="ctl00$Main$grdLotes$ctl02$ctl34" type="text" value="0" size="4" class="TextBox" style="width:20px;" /><span>I</span></td>
</tr>
</table>
</div>
</td></tr></table>
</div>
<input type=hidden name=ctl00_Main_sg1$hdnScrollPos id=ctl00_Main_sg1$hdnScrollPos>
<script language=javascript>
<!--
setTimeout("initScrollingGrid('ctl00_Main_sg1', 'ctl00_Main_grdLotes', false, 0, 0);", 50)
//--></script></td></tr></table>
|
|
|
|

|
I have an edit linkbutton as a column value and when I wish to edit a
cell (esp. if it's the first row in the grid) the header duplicates
itself. Is there a fix for this?
RF
|
|
|
|

|
Hi! The source is great! In May 2007 you mentioned wanting to rewrite it to VS2005 .NET 2.0. I see you haven't done this yet, and there is no reason to! Automatic conversion by VS2005 works like a charme...
thnx Dennis
modified on Tuesday, February 26, 2008 3:21 PM
|
|
|
|

|
How do you do this automatic conversion? I have implemented a ScrollingGrid in a project but I'm not getting scroll bars and the appearance of my previously existing datagrid is messed up (font size, width, scrollbars, etc)
Help?
|
|
|
|

|
Using a datagrid with this control in ASP.NET 2.0 works fine, but it does not work with the gridview control. I believe that's what needs updating.
|
|
|
|

|
Thanks a lot for this Mate. This was really useful.
|
|
|
|

|
Hello anybody
This control can't use for ajax(Microsoft). Help me
|
|
|
|

|
This is an example of a programmer acting like a user! No detail whatsoever, just "Help me its broken"
|
|
|
|
 |
|
|
General News Suggestion Question Bug Answer Joke Rant Admin
|
A cross-browser container control for a DataGrid to freeze the header row and sync the header when the DataGrid is scrolled horizontally.
| Type | Article |
| Licence | CPOL |
| First Posted | 14 Sep 2005 |
| Views | 615,042 |
| Bookmarked | 204 times |
|
|