locked
GridViewEx RRS feed

  • Question

  • User-83134775 posted

     Here's a class that extends the standard GridView. The code is not entirely made by me. It's basicaly a lot snippets from other posts/articles/blogs polished and combined into a single class: 

     

    #region Using directives
    
    using System;
    using System.ComponentModel;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    
    #endregion
    
    namespace MyWebControls
    {
    
    	public class GridViewEx : GridView
    	{
    		#region Properties
    
    		/// <summary>
    		/// When true and the GridView is inside a container with overflow this will make the header fixed. 
    		/// Only the rest of the rows will scroll.
    		/// </summary>
    		/// <remarks>
    		///	Works only in IE.
    		/// </remarks>
    		[Category("Behaviour")]
    		[Themeable(true)]
    		[Bindable(false)]
    		[DefaultValue(false)]
    		public bool FreezeHeader
    		{
    			get
    			{
    				if (ViewState["FreezeHeader"] == null)
    					return false;
    
    				return (bool)ViewState["FreezeHeader"];
    			}
    			set
    			{
    				ViewState["FreezeHeader"] = value;
    			}
    		}
    
    		[Category("Behaviour")]
    		[Themeable(true)]
    		[Bindable(BindableSupport.No)]
    		[DefaultValue(false)]
    		public bool ShowWhenEmpty
    		{
    			get
    			{
    				if (ViewState["ShowWhenEmpty"] == null)
    					return false;
    
    				return (bool)ViewState["ShowWhenEmpty"];
    			}
    			set
    			{
    				ViewState["ShowWhenEmpty"] = value;
    			}
    		}
    
    
    		protected GridViewRow _footerRow2;
    		public override GridViewRow FooterRow
    		{
    			get
    			{
    				GridViewRow f = base.FooterRow;
    				if (f != null)
    					return f;
    				else
    					return _footerRow2;
    			}
    		}
    
    		protected GridViewRow _headerRow2;
    		public override GridViewRow HeaderRow
    		{
    			get
    			{
    				GridViewRow h = base.HeaderRow;
    				if (h != null)
    					return h;
    				else
    					return this._headerRow2;
    			}
    		}
    
    		[Bindable(BindableSupport.Yes, BindingDirection.OneWay)]
    		public override string Caption
    		{
    			get
    			{
    				return base.Caption;
    			}
    			set
    			{
    				base.Caption = value;
    			}
    		}
    
    
    		/// <summary>
    		/// Enable/Disable MultiColumn Sorting.
    		/// </summary>
    		[
    		Description("Whether Sorting On more than one column is enabled"),
    		Category("Behavior"),
    		DefaultValue("false"),
    		]
    		public bool AllowMultiColumnSorting
    		{
    			get
    			{
    				object o = ViewState["EnableMultiColumnSorting"];
    				return (o != null ? (bool)o : false);
    			}
    			set
    			{
    				AllowSorting = true;
    				ViewState["EnableMultiColumnSorting"] = value;
    			}
    		}
    		/// <summary>
    		/// Get or Set Image location to be used to display Ascending Sort order.
    		/// </summary>
    		[
    		Description("Image to display for Ascending Sort"),
    		Category("Misc"),
    		Editor("System.Web.UI.Design.UrlEditor", typeof(System.Drawing.Design.UITypeEditor)),
    		DefaultValue(""),
    
    		]
    		public string SortAscImageUrl
    		{
    			get
    			{
    				object o = ViewState["SortImageAsc"];
    				return (o != null ? o.ToString() : "");
    			}
    			set
    			{
    				ViewState["SortImageAsc"] = value;
    			}
    		}
    		/// <summary>
    		/// Get or Set Image location to be used to display Ascending Sort order.
    		/// </summary>
    		[
    		Description("Image to display for Descending Sort"),
    		Category("Misc"),
    		Editor("System.Web.UI.Design.UrlEditor", typeof(System.Drawing.Design.UITypeEditor)),
    		DefaultValue(""),
    		]
    		public string SortDescImageUrl
    		{
    			get
    			{
    				object o = ViewState["SortImageDesc"];
    				return (o != null ? o.ToString() : "");
    			}
    			set
    			{
    				ViewState["SortImageDesc"] = value;
    			}
    		}
    
    		public DataControlRowState? RowState
    		{
    			get
    			{
    				return (DataControlRowState?)ViewState["RowState"];
    			}
    			set
    			{
    				ViewState["RowState"] = value;
    
    			}
    		}
    
    		#endregion
    		#region Life Cycle
    
    		protected override void OnSorting(GridViewSortEventArgs e)
    		{
    			if (AllowMultiColumnSorting)
    				e.SortExpression = GetSortExpression(e);
    
    			base.OnSorting(e);
    		}
    
    		protected override void OnRowCreated(GridViewRowEventArgs e)
    		{
    			if (e.Row.RowType == DataControlRowType.Header)
    			{
    				if (SortExpression != String.Empty)
    					DisplaySortOrderImages(SortExpression, e.Row);
    			}
    
    			base.OnRowCreated(e);
    		}
    
    		protected override GridViewRow CreateRow(int rowIndex, int dataSourceIndex, DataControlRowType rowType, DataControlRowState rowState)
    		{
    			if (RowState.HasValue)
    				return base.CreateRow(rowIndex, dataSourceIndex, rowType, RowState.Value);
    			else
    				return base.CreateRow(rowIndex, dataSourceIndex, rowType, rowState);
    		}
    
    		#endregion
    		#region Protected Methods
    		/// <summary>
    		///  Get Sort Expression by Looking up the existing Grid View Sort Expression 
    		/// </summary>
    		protected string GetSortExpression(GridViewSortEventArgs e)
    		{
    			string[] sortColumns = null;
    			string sortAttribute = SortExpression;
    
    			//Check to See if we have an existing Sort Order already in the Grid View.	
    			//If so get the Sort Columns into an array
    			if (sortAttribute != String.Empty)
    			{
    				sortColumns = sortAttribute.Split(",".ToCharArray());
    			}
    
    			//if User clicked on the columns in the existing sort sequence.
    			//Toggle the sort order or remove the column from sort appropriately
    
    			if (sortAttribute.IndexOf(e.SortExpression) > 0 || sortAttribute.StartsWith(e.SortExpression))
    				sortAttribute = ModifySortExpression(sortColumns, e.SortExpression);
    			else
    				sortAttribute += String.Concat(",", e.SortExpression, " ASC ");
    			return sortAttribute.TrimStart(",".ToCharArray()).TrimEnd(",".ToCharArray());
    
    		}
    
    		public void SaveAll()
    		{
    			for (int i = 0; i < this.Rows.Count; i++)
    			{
    				this.UpdateRow(i, false);
    			}
    		}
    
    		/// <summary>
    		///  Toggle the sort order or remove the column from sort appropriately
    		/// </summary>
    		protected string ModifySortExpression(string[] sortColumns, string sortExpression)
    		{
    
    			string ascSortExpression = String.Concat(sortExpression, " ASC ");
    			string descSortExpression = String.Concat(sortExpression, " DESC ");
    
    			for (int i = 0; i < sortColumns.Length; i++)
    			{
    
    				if (ascSortExpression.Equals(sortColumns[i]))
    				{
    					sortColumns[i] = descSortExpression;
    				}
    
    				else if (descSortExpression.Equals(sortColumns[i]))
    				{
    					Array.Clear(sortColumns, i, 1);
    				}
    			}
    
    			return String.Join(",", sortColumns).Replace(",,", ",").TrimStart(",".ToCharArray());
    
    		}
    		/// <summary>
    		///  Lookup the Current Sort Expression to determine the Order of a specific item.
    		/// </summary>
    		protected void SearchSortExpression(string[] sortColumns, string sortColumn, out string sortOrder, out int sortOrderNo)
    		{
    			sortOrder = "";
    			sortOrderNo = -1;
    			for (int i = 0; i < sortColumns.Length; i++)
    			{
    				if (sortColumns[i].StartsWith(sortColumn))
    				{
    					sortOrderNo = i + 1;
    					if (AllowMultiColumnSorting)
    						sortOrder = sortColumns[i].Substring(sortColumn.Length).Trim();
    					else
    						sortOrder = ((SortDirection == SortDirection.Ascending) ? "ASC" : "DESC");
    				}
    			}
    		}
    		/// <summary>
    		///  Display a graphic image for the Sort Order along with the sort sequence no.
    		/// </summary>
    		protected void DisplaySortOrderImages(string sortExpression, GridViewRow dgItem)
    		{
    			string[] sortColumns = sortExpression.Split(",".ToCharArray());
    
    			for (int i = 0; i < dgItem.Cells.Count; i++)
    			{
    				if (dgItem.Cells[i].Controls.Count > 0 && dgItem.Cells[i].Controls[0] is LinkButton)
    				{
    					string sortOrder;
    					int sortOrderNo;
    					string column = ((LinkButton)dgItem.Cells[i].Controls[0]).CommandArgument;
    					SearchSortExpression(sortColumns, column, out sortOrder, out sortOrderNo);
    					if (sortOrderNo > 0)
    					{
    						string sortImgLoc = (sortOrder.Equals("ASC") ? SortAscImageUrl : SortDescImageUrl);
    
    						if (sortImgLoc != String.Empty)
    						{
    							Image imgSortDirection = new Image();
    							imgSortDirection.ImageUrl = sortImgLoc;
    							dgItem.Cells[i].Controls.Add(imgSortDirection);
    							//Label lblSortOrder = new Label();
    							//lblSortOrder.Font.Size = FontUnit.Small;
    							//lblSortOrder.Text = sortOrderNo.ToString();
    							//dgItem.Cells[i].Controls.Add(lblSortOrder);
    
    						}
    						else
    						{
    
    							//Label lblSortDirection = new Label();
    							//lblSortDirection.Font.Size = FontUnit.XSmall;
    							//lblSortDirection.Font.Name = "webdings";
    							//lblSortDirection.EnableTheming = false;
    							//lblSortDirection.Text = (sortOrder.Equals("ASC") ? "5" : "6");
    							//dgItem.Cells[i].Controls.Add(lblSortDirection);
    
    							if (AllowMultiColumnSorting)
    							{
    								Literal litSortSeq = new Literal();
    								litSortSeq.Text = sortOrderNo.ToString();
    								dgItem.Cells[i].Controls.Add(litSortSeq);
    
    							}
    						}
    					}
    				}
    			}
    		}
    
    		protected override int CreateChildControls(System.Collections.IEnumerable dataSource, bool dataBinding)
    		{
    			int numRows = base.CreateChildControls(dataSource, dataBinding);
    
    			//no data rows created, create empty table if enabled
    			if (numRows == 0 && ShowWhenEmpty)
    			{
    				//create table
    				Table table = new Table();
    				table.ID = this.ID;
    
    				//convert the exisiting columns into an array and initialize
    				DataControlField[] fields = new DataControlField[this.Columns.Count];
    				this.Columns.CopyTo(fields, 0);
    
    				if (this.ShowHeader)
    				{
    					//create a new header row
    					_headerRow2 = base.CreateRow(-1, -1, DataControlRowType.Header, DataControlRowState.Normal);
    
    					this.InitializeRow(_headerRow2, fields);
    					table.Rows.Add(_headerRow2);
    				}
    
    				//create the empty row
    				GridViewRow emptyRow = new GridViewRow(-1, -1, DataControlRowType.EmptyDataRow, DataControlRowState.Normal);
    
    				TableCell cell = new TableCell();
    				cell.ColumnSpan = this.Columns.Count;
    				cell.Width = Unit.Percentage(100);
    				if (!String.IsNullOrEmpty(EmptyDataText))
    					cell.Controls.Add(new LiteralControl(EmptyDataText));
    
    				if (this.EmptyDataTemplate != null)
    					EmptyDataTemplate.InstantiateIn(cell);
    
    				emptyRow.Cells.Add(cell);
    				table.Rows.Add(emptyRow);
    
    				if (this.ShowFooter)
    				{
    					//create footer row
    					_footerRow2 = base.CreateRow(-1, -1, DataControlRowType.Footer, DataControlRowState.Normal);
    
    					this.InitializeRow(_footerRow2, fields);
    					table.Rows.Add(_footerRow2);
    				}
    
    				this.Controls.Clear();
    				this.Controls.Add(table);
    			}
    
    			//does not work on Gecko
    			if (this.FreezeHeader && this.HeaderRow != null)
    			{
    				this.HeaderRow.Style["top"] = "expression(this.offsetParent.scrollTop)";
    				this.HeaderRow.Style["position"] = "relative";
    				this.HeaderRow.Style["zindex"] = "2";
    			}
    
    			return numRows;
    		}
    
    		#endregion
    	}
    }
    
    Entra features added are:
    • Posibility to freeze the header (when the grid is placed in a container with overflow:scroll or auto)
    • Show the header/footer rows even when the datasource is empty.
    • Show images in the header that indicate the sort column and sort direction.
    • Caption property is bindable
    • Buld Editing (set RowState to Edit then call SaveAll())
    • Sort by multiple columns (not properly implemented yet as I didn't need it)
    Please post any suggestions and/or bugs that you can find here. Also, anyone who has made something that's not included here and is willing to share is more than welcomed to to so :D
    Friday, July 28, 2006 9:06 AM

All replies

  • User-2110850132 posted

    This is a great class indeed, thanks for supplying it!

    However, if I try fetching text from a code-behind function inside the EmptyDataTemplate it doesn't show the text. When debugging it enters the function and returns the text, but it doesn't get displayed. When using the asp:GridView the text shows up nicely (but of course without the header and footer).

    Example:

    <EmptyDataTemplate>

    <asp:Label id="lblNoData" runat="server" Text='<%# GetNoMessagesText() %>' SkinID="Info"></asp:Label>

    </EmptyDataTemplate>

    Do you have any idea why this is and if it can be fixed?

     

     

     

     

    Tuesday, August 15, 2006 3:21 PM
  • User-83134775 posted
    It's a little hackish, but should work just fine. Instead of initializing emptyRow like this:

    GridViewRow emptyRow;
    emptyRow = new GridViewRow(-1, -1, DataControlRowType.EmptyDataRow, DataControlRowState.Normal);
    TableCell cell = new TableCell();
    cell.ColumnSpan = this.Columns.Count;
    cell.Width Unit.Percentage(100);

    if 
    (!String.IsNullOrEmpty(EmptyDataText))
        cell.Controls.Add(
    new LiteralControl(EmptyDataText));

    if 
    (this.EmptyDataTemplate != null)
        EmptyDataTemplate.InstantiateIn(cell)
    ;

    emptyRow.Cells.Add(cell);


    Just use the already initialized row:

    emptyRow = this.Controls[0].Controls[0as GridViewRow;


    The row is already initialized because of the call to base.CreateChildControls().
    Thursday, August 17, 2006 8:29 AM
  • User-2110850132 posted

    Thanks, that did the trick.

    I ended up rewriting it a bit so it now looks like this:

     

     
    //create the empty row
    GridViewRow emptyRow;
    if (this.EmptyDataTemplate != null)
        emptyRow = this.Controls[0].Controls[0] as GridViewRow;
    else
    {
        emptyRow = new GridViewRow(-1, -1, DataControlRowType.EmptyDataRow, DataControlRowState.Normal);
    
        TableCell cell = new TableCell();
        cell.ColumnSpan = this.Columns.Count;
        cell.Width = Unit.Percentage(100);
        if (!String.IsNullOrEmpty(EmptyDataText))
            cell.Controls.Add(new LiteralControl(EmptyDataText));
            emptyRow.Cells.Add(cell);
    }
    table.Rows.Add(emptyRow);
    
     
    Friday, August 18, 2006 9:53 AM
  • User-1553550390 posted

    Hi there,

     I think you would be more comfortable with a solution like

    1    //create the empty row
    2    GridViewRow emptyRow = new GridViewRow(-1, -1, DataControlRowType.EmptyDataRow, DataControlRowState.Normal);
    3    //add row to table
    4    tbl.Rows.Add(emptyRow);
    5    //initialize row
    6    InitializeRow(emptyRow, fields);
    This way you could use the standard methods of the GridView without having to rewrite everything.
    Additionaly I came up with one problem concerning the line
     
    1    Table table = new Table();
    2    table.ID = this.ID;
    
     

     I wouldn't do that, because this changes the IDs of the controls within the grid. The method of the GridView (CreateChildControls) creates the table as "ctl00" and changing the ID could cause problems on postbacks.

    kind regards,

    Chris

    Thursday, October 19, 2006 8:29 AM
  • User2090127564 posted

    Hi,

    I've used part of this customcontrol in the past to make a footerrow with insert functionality display/work when the gridview is empty. This has always worked great. Buttons and textboxes in the footer cuold always be used normaly when an empty gridview was encountered.

    Now I've got some search functionalty embedded in the header and I'm using this customcontrol to show the gridview when it is empty.

    This time it's not working though.

    When an empty gridview is returned after a search has been done, the searchbutton and textboxes are shown. The sort-links returned by the GetHeader are not however. It seems the header never gets initialized properly when a search doesn't have any results. When a new search is performed after an empty search, a postback occurs, but the RowCommand is never called.

    I've found that the properties HeaderText and SortExpression of the templatefield are not used when the templatefield contains a HeaderTemplate. Therefor the build-in functionality of sorting could not be used. The GetHeader function is for creating the sort-link in the header.

    Because the search-textboxes are within the gridview, they do not automatically persist their value during postbacks. I've come up with a way to dynamically build and fill the filter parameters and expression and use this to persist (re-fill) the search fields.

    I'm using caching and filterparameters to fill and search the data in the gridview.

    My Code: 

    protected override int CreateChildControls:
    Same as above (minus FreezeHeader, I'm using only the ShowWhenEmpty functionality)
    SelectMethod (because of caching only called when necessary):
    public DataSet gvOrderList_Select(string sort)
    {
    string sql = "SELECT O.*, OS.Status AS StatusNaam, K.Achternaam FROM (ORDER O LEFT JOIN OrderStatus OS ON O.Status = OS.Id) LEFT JOIN Klant K ON O.KlantId = K.Id";

    if (!string.IsNullOrEmpty(sort))
    {
    if (sort.Contains("IngangsDatum"))
    sort = sort.Replace("IngangsDatum", "O.IngangsDatum");
    if (sort.Contains("Status"))
    sort = sort.Replace("Status", "O.Status");
    sql += " ORDER BY " + sort + ";";
    }
    else
    sql += " ORDER BY O.IngangsDatum DESC;";

    DataSet ds = db.Select(sql);

    HttpContext.Current.Cache["CacheodsOrderList"] = ds;

    return ds;
    }
    OnRowCommand:
    protected void gvOrderList_RowCommand(object sender, GridViewCommandEventArgs e)
    {
    switch (e.CommandName)
    {
    case "new":
    break;

    case "edit":
    break;

    case "del":
    break;

    case "search":
    string search;

    odsOrderList.FilterParameters.Clear();

    search = ((TextBox)gvOrderList.HeaderRow.FindControl("tbSearchOrdernummer")).Text;
    if (!string.IsNullOrEmpty(search))
    odsOrderList.FilterParameters.Add("Ordernummer", search);
    search = ((TextBox)gvOrderList.HeaderRow.FindControl("tbSearchDatumVan")).Text;
    if (!string.IsNullOrEmpty(search))
    odsOrderList.FilterParameters.Add("DatumVan", TypeCode.DateTime, search);
    search = ((TextBox)gvOrderList.HeaderRow.FindControl("tbSearchDatumTot")).Text;
    if (!string.IsNullOrEmpty(search))
    odsOrderList.FilterParameters.Add("DatumTot", TypeCode.DateTime, search);
    search = ((TextBox)gvOrderList.HeaderRow.FindControl("tbSearchAchternaam")).Text;
    if (!string.IsNullOrEmpty(search))
    odsOrderList.FilterParameters.Add("Achternaam", search);
    search = ((DropDownList)gvOrderList.HeaderRow.FindControl("ddlSearchStatus")).SelectedValue;
    if (!string.IsNullOrEmpty(search))
    odsOrderList.FilterParameters.Add("Status", TypeCode.Int32, search);

    BuildFilterExpression();

    break;

    default:
    break;
    }
    OnDataBound:
    protected void gvOrderList_DataBound(object sender, EventArgs e)
    {
    BuildFilterExpression();
    }
    GetHeader:
    protectedstring GetHeader(string HeaderText, string SortExpression)
    {
    return "<a href=\"javascript:__doPostBack('" + gvOrderList.UniqueID + "','Sort$" + SortExpression + "')\"><font class=\"titel\">" + HeaderText + "</font></a>";
    }
    BuildFilterExpression:
    protected void BuildFilterExpression()
    {
    if (odsOrderList.FilterParameters.Count > 0)
    {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < odsOrderList.FilterParameters.Count; ++i)
    {
    switch (odsOrderList.FilterParameters[i].Name)
    {
    case "Ordernummer":
    ((TextBox)gvOrderList.HeaderRow.FindControl("tbSearchOrdernummer")).Text = odsOrderList.FilterParameters["Ordernummer"].DefaultValue;
    sb.Append("Ordernummer LIKE '{" + i.ToString() + "}%' AND ");
    break;
    case "DatumVan":
    ((TextBox)gvOrderList.HeaderRow.FindControl("tbSearchDatumVan")).Text = odsOrderList.FilterParameters["DatumVan"].DefaultValue;
    sb.Append("IngangsDatum >= #{" + i.ToString() + "}# AND ");
    break;
    case "DatumTot":
    ((TextBox)gvOrderList.HeaderRow.FindControl("tbSearchDatumTot")).Text = odsOrderList.FilterParameters["DatumTot"].DefaultValue;
    sb.Append("IngangsDatum <= #{" + i.ToString() + "}# AND ");
    break;
    case "Achternaam":
    ((TextBox)gvOrderList.HeaderRow.FindControl("tbSearchAchternaam")).Text = odsOrderList.FilterParameters["Achternaam"].DefaultValue;
    sb.Append("Achternaam LIKE '{" + i.ToString() + "}%' AND ");
    break;
    case "Status":
    ((DropDownList)gvOrderList.HeaderRow.FindControl("ddlSearchStatus")).SelectedIndex = Convert.ToInt32(odsOrderList.FilterParameters["Status"].DefaultValue);
    sb.Append("Status = {" + i.ToString() + "} AND ");
    break;
    default:
    break;
    }
    }
    odsOrderList.FilterExpression = (sb.Remove(sb.Length - 5, 5)).ToString();
    }
    }
    Gridview:
    <CustomControls:EmptyGridView ID="gvOrderList" runat="server" DataSourceID="odsOrderList" AllowSorting="true" AllowPaging="true" PageSize="10" PagerSettings-Position="Top" AutoGenerateColumns="false" ShowFooter="true" ShowHeader="true" DataKeyNames="Id" OnDataBound="gvOrderList_DataBound" OnRowCommand="gvOrderList_RowCommand" EmptyDataText="NIEUW - Geen orders" EnableViewState="false">
    <Columns>
    <asp:TemplateField>
    <HeaderTemplate>
    <asp:Button ID="btnGVSearch" runat="server" CommandName="search" TabIndex="6" Text="Zoek" CssClass="Teksten" />
    </HeaderTemplate>
    <ItemTemplate>
    <asp:ImageButton ID="ibtnEdit" runat="server" CommandName="edit" CommandArgument='<%# Eval("Id") %>' ImageUrl="~/images/edit.gif" />&nbsp;<asp:ImageButton ID="ibtnDel" runat="server" CommandName="del" CommandArgument='<%# Eval("Id") %>' OnClientClick="return confirm('Weet u zeker dat u deze order wilt verwijderen?')" ImageUrl="~/images/del.gif" />
    </ItemTemplate>
    <FooterTemplate>
    <hr width="100%" />
    </FooterTemplate>
    <HeaderStyle HorizontalAlign="Left" VerticalAlign="Bottom" />
    <ItemStyle Width="75" HorizontalAlign="Left" VerticalAlign="Top" />
    </asp:TemplateField>
    <asp:TemplateField>
    <HeaderTemplate>
    <%# GetHeader("Code", "Ordernummer") %>
    <br />
    <asp:TextBox ID="tbSearchOrdernummer" runat="server" TabIndex="1" />
    </HeaderTemplate>
    <ItemTemplate>
    <%# Eval("Ordernummer") %>
    </ItemTemplate>
    <HeaderStyle HorizontalAlign="Left" VerticalAlign="Top" />
    <ItemStyle HorizontalAlign="Left" VerticalAlign="Top" />
    </asp:TemplateField>
    ...
    SOME MORE TEMPLATEFIELDS
    ...
    </Columns>
    </CustomControls:EmptyGridView>

    <asp:ObjectDataSource ID="odsOrderList" runat="server"
    TypeName="ObjectDataSources.odsOrderList"
    EnableCaching="true"
    CacheKeyDependency="CacheodsOrderList"
    SelectMethod="gvOrderList_Select"
    SortParameterName="sort"
    >
    </asp:ObjectDataSource>
    Any light you could shed on this would be greatly appreciated.
    H. Deur 
    Monday, November 20, 2006 12:10 PM
  • User1933603941 posted

     

    e.SortBLOCKED EXPRESSION is undefined, it does not seem to come with the GridViewEventArgs,

    let me know what the space stands for in the middle or if a function or property is missing.

    Friday, February 2, 2007 4:38 PM
  • User-1400649960 posted

    The line should be:

      

    if (sortAttribute.IndexOf(e.SortExpression) > 0 || sortAttribute.StartsWith(e.SortExpression))
    
     
    Tuesday, August 7, 2007 5:23 AM
  • User-1400649960 posted

    Hmm. No matter what I tried, I could not get the code to work.

     Here's what I did:

    Started a new web project, created a folder called MyWebControls, and added a Web User Control to that. In the code-behind, I pasted the code code, and corrected where appropriate (The EXPRESSION BLOCKED).

    Got this:

    Error 1 Make sure that the class defined in this code file matches the 'inherits' attribute, and that it extends the correct base class (e.g. Page or UserControl). C:\Documents and Settings\..WebSite4\MyWebControls\GridViewExample.ascx.cs 1 33 C:\...\WebSite4\

    I tried messing around in the ASPX file, by adding the MyWebControls namespace to the inherits bit:

    <%@ Control Language="C#" AutoEventWireup="true" CodeFile="GridViewExample.ascx.cs" Inherits="MyWebControls_GridViewEx" %>

    At times I got this error:

    Missing partial modifier on declaration of type 'GridViewExample'; another partial declaration of this type exists

    Could anyone try to either give me a more detailed description of steps to take, or just specifying where I went wrong? It's been some time since I messed with ASP.NET, and I probably am overlooking something real easy. However, I have spent quite a bit of time on this already, and am hoping someone can give me a proper kick in the right direction.

    Thanks!

    Peter

    Tuesday, August 7, 2007 4:49 PM
  • User-1400649960 posted

    Doh. I think I just figured it out. Instead of creating it as a Web User Control, it helps if I create it as a Web Control Library.

    Tuesday, August 7, 2007 5:03 PM
  • User681754118 posted

    Hey can you help me out?  What is the correction for the "BLOCKED EXPRESSION" stuff?  Thanks.

    Wednesday, August 15, 2007 4:43 PM
  • User122996939 posted
    When using this approach to get header & footer visible when there is no record, it works. Except for one thing. If I've got a Button in the footer, its Click event will not fire. Any ideas?
    Thursday, August 16, 2007 8:53 AM
  • User-1400649960 posted

    One of them is

    if (sortAttribute.IndexOf(e.SortExpression) > 0 || sortAttribute.Startswith(e.SortExpression))

     Not sure what the other one is, as I'm at work, but it's something starting with expression.

     
    Monday, August 20, 2007 5:10 AM
  • User-751023921 posted

    There is no need to do all these things if you are using Sqldatasource then just do the following thing,

     1) Insert new row in sqldatasource

     2) and just after that set gridview's edit index=0,

     So, it will open that newly added blank row in edit mode and thats all.

    Monday, June 16, 2008 7:12 AM
  • User-1395508978 posted

    Great class!

    I really can't understand why MS did not implement the ability to display a footer/header when the grid is empty.

    Anyway, I had problems with the GridViewEx when having input controls in the footer. They do not maintain viewstate on postbacks. Therefore I did a little tweak to solve that:

    The ViewState is maintained because the footer is not the same footer as the original footer. As you can see in the code, there is newly created footer named _footerRow2. Therefore the viewstate will not be kept on postback. To fix this simply add a new readonly property exposing the _footerRow2. This way it is possible to find the controls in the new footer (using myGrid.FooterRowEmpty.findControls("NameOfInputField") and setting the values manually. If using the myGrid.FooterRow, you will find the controls, but they will of course not be visible.

    Here is the code for the property:

    public virtual GridViewRow FooterRowEmpty
            {
                get
                {
                    if (_footerRow2 == null)
                    {
                        EnsureChildControls();
                    }
                    return _footerRow2;
                } 
            }

    And here is the usage on the footerrows:

     

    Private Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.PreRender
            If Not grdData Is Nothing Then
                Dim footerRow As GridViewRow = grdData.FooterRow
                If grdData.Rows.Count = 0 AndAlso Not grdData.FooterRowEmpty Is Nothing Then
                    footerRow = grdData.FooterRowEmpty
                    LoadFilterValues(footerRow) 'Put values into the fields in the footer.
                    SetDefaultButtonAndFocus(footerRow)
                ElseIf Not footerRow Is Nothing Then
                    SetDefaultButtonAndFocus(footerRow)
                End If
            End If
        End Sub
      This code will put the values back in the controls (LoadFilterValues) and set default button and focus (SetDefaultButtonAndFocus). You will have to write these yourself ;)

     

    Thursday, February 19, 2009 5:19 AM
  • User706013099 posted

    Sounds as if your issue may be the same or related to mine - but just to check..

    For several years I have used the relatively crude approach of declaring a GridView with a FooterTemplate on each column for inserts and an EmptyDataTemplate containing identical controls for inserting when there is no starting data. Then in code behind I test if the row count is 0 and if so find each control from the EmptyData template and if not do the same for the FooterRow. All works but very irritating.

    I have never been interested in any crude hack such as binding to an empty DataTable. So now I am trying to build a custom GridView using the approach to override CreateChildControls broadly as set out by CISCBrain with a few slight modifications (in addition I am also autogenerating command columns but these work OK so I have removed this processing from the code below).

    Protected Overrides Function CreateChildControls(ByVal dataSource As System.Collections.IEnumerable, ByVal dataBinding As Boolean) As Integer
            Dim numRows As Integer = MyBase.CreateChildControls(dataSource, dataBinding)
            If numRows = 0 And (ShowHeaderWhenEmpty Or ShowFooterWhenEmpty) Then
                Dim tab As Table = Me.CreateChildTable()
                Dim flds As DataControlField() = New DataControlField(Me.Columns.Count - 1) {}
                Me.Columns.CopyTo(flds, 0)
                If ShowHeaderWhenEmpty Then
                    _headerRow = MyBase.CreateRow(-1, -1, DataControlRowType.Header, DataControlRowState.Normal)
                    Me.InitializeRow(_headerRow, flds)
                    tab.Rows.Add(_headerRow)
                    MyBase.OnRowCreated(New GridViewRowEventArgs(_headerRow))
                End If
                If Insertable And ShowFooterWhenEmpty Then
                    _footerRow = MyBase.CreateRow(-1, -1, DataControlRowType.Footer, DataControlRowState.Normal)
                    Me.InitializeRow(_footerRow, flds)
                    Me.ShowFooter = True
                    tab.Rows.Add(_footerRow)
                    MyBase.OnRowCreated(New GridViewRowEventArgs(_footerRow))
                End If
                Me.Controls.Clear()
                Me.Controls.Add(tab)
            End If
            Return numRows
        End Function


    And I have the following properties:

    Protected _headerRow As GridViewRow = Nothing
        Public Overloads Overrides ReadOnly Property HeaderRow() As GridViewRow
            Get
                If Not MyBase.HeaderRow Is Nothing Then
                    Return MyBase.HeaderRow
                Else
                    Return _headerRow
                End If
            End Get
        End Property
        Protected _footerRow As GridViewRow = Nothing
        Public Overloads Overrides ReadOnly Property FooterRow() As GridViewRow
            Get
                If Not MyBase.FooterRow Is Nothing Then
                    Return MyBase.FooterRow
                Else
                    Return _footerRow
                End If
            End Get
        End Property


    All this works and I can retrieve values from the controls in the footer row whether there is starting data or not.

    However, the problem I have is if the footer includes databound controls such as DropDownLists. In this case, I get an error that the Bind (or Eval) can only be used in the context of a databound control. This did not happen when I was using the EmptyDataTemplate for this purpose, so it would seem that somehow the footer row is not getting initialized properly. What do I need to do to ensure that the footer is properly initialized and databound? Does your code for maintaining viewstate on postbacks relate to my issue? Hopefully there is a solution which can be handled in the custom GridView class rather than requiring specific page code to initialize the footer - if the latter is the case then I am really back to square one as even the EmptyDataTemplate approach did this declaratively.

    Jon

    Sunday, September 27, 2009 3:58 AM