Potential differences in gridview events within a master page - c#

I have a master page that has a few child pages, this master page happens to contain a grid view because all child pages use one. I've gotten to the stage where I've realized small changes need to be appended to the grid view onrowdatabound event for individual child pages.
As an example I have 3 pages, A.aspx, B.aspx, C.aspx. All three use the grid and bind different data to the gridview that is in the master page. A & B are pretty much identical and there aren't any problems but C wants row attributes to be appended that A & B don't need.
How can I apply these changes without causing problems to the other pages?
[Optional] Is this the complete wrong way to go, and/or should I make them separate pages?
Little diagram of my situation

You can bind an event to a GridView programatically. So in page C.aspx you could do something like this:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
//find the gridview in the master page
GridView gv = Master.FindControl("GridView1") as GridView;
//add the event to the gridview
gv.RowDataBound += GridView1Master_RowDataBound;
gv.DataSource = mySource;
gv.DataBind();
}
}
protected void GridView1Master_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.BackColor = Color.Red;
}
}

Related

One GridView and many LinkButtons (asp .net WebForms)

I have a GridView and dynamically added LinkButton in GridView cell:
protected void TestGrid_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
foreach (var l in links)
{
e.Row.Cells[6].Controls.Add(l.button);
PostBackTrigger trigger = new PostBackTrigger();
trigger.ControlID = l.button.ID;
UpPanel.Triggers.Add(trigger);
}
}
}
Links are added, its ok, but clicking on link, GridView refreshes and links disappears. When I delete this condition from page_load function, I have a problem with page index changing event - GridView does not refresh:
if (!IsPostBack)
{
TestGrid.DataBind();
}
What can I do to stop links disappearing and keep page index functional? And is there a better way to add many LinkButtons in one GridView cell? Thank you!

trigger an eventhandler on postback c#

I am pretty new to c# programming.
I have an issue that follows:
I have a GridView on a web form, a DropDownList and a Label control. When i select a value from a DDL a Grid View is populated with rows from the database that equal the DDL condition(in my case DDL represent Countries, GV lists the Cities).
When i delete the last City from a GV using a built in GV Delete function i would like to automatically write in a Label that there are no more Cities in selected Country.
How can i achieve that?
I tried to put
protected void GridView1_RowDeleted1(object sender, GridViewDeletedEventArgs e)
{
if (GridView1.Rows.Count == 0)
{
LabelGrid.Text = "No more cities.";
}
}
but it didn't work.
Thanks for your help
Consider using PreRender event, when that event runs the Row.Count property contains the correct value. (decremented after delete)
protected void GridView1_PreRender(object sender, EventArgs e)
{
if (GridView1.Rows.Count == 0)
{
LabelGrid.Text = "No more cities.";
}
}

adding footer value to datagridview in C#

I am having 2 datatables. One is having the actual value of that table selected by the user and the next is having the aggregate value for that table i.e any grand total or avg. I want to display this as the footer in C# datagridview. How can I do that??? In asp.net we have RowDataBound event like that similar something is there in C# also but what it is i'm not able to find.
You can use ondatabound event of GridView for populating footer. Sample:
protected void GridView1_DataBound(object sender, EventArgs e)
{
GridView grid = sender as GridView;
grid.FooterRow.Cells[0].Text = CustomDataSource.GetAggregated.Rows[0]["Name"].ToString();
grid.FooterRow.Cells[1].Text = CustomDataSource.GetAggregated.Rows[0]["Total"].ToString();
}

Nesting Repeater in Gridview: Hiding gridview row and repeater header if data is not there in repeater

I have nested a repeater control in Gridview. Right now it is showing gridview rows and repeater header for every case(whether data is there or not for that particular grid view row in the repeater control). I want to hide the gridview row and repeater control header when there is no data present for that particular gridview row.
Thanks,
That case I handled at code level by filtering the resulted data table.
Now the another problem I am facing:
I have allowed the paging on the gridview i.e. pagesize 3.
When page loads it works fine, but when I go to page 2 then it generates following error:
Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index
Below is the code to fill the grid, paging and fill repeater on rowdatabound event of grid.
private void FillGrid()
{
clsCustomFunctions objShort = new clsCustomFunctions();
grd1.DataSource = objShort.GetAll();
}
protected void grd1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
try
{
FillGrid();
grd1.PageIndex = e.NewPageIndex;
grd1.DataBind();
}
catch (Exception ex)
{
lblMsg.Text = ex.Message;
}
}
protected void grd1_RowDataBound(object sender, GridViewRowEventArgs e)
{
clsCustomFunctions objShort = new clsCustomFunctions();
if (e.Row.RowType == DataControlRowType.DataRow)
{
((HtmlTable)e.Row.FindControl("gridTable")).BgColor = "#006699";
Repeater rpt = (Repeater)e.Row.FindControl("rpt1");
rpt.DataSource = objShort.GetResult(Convert.ToInt32(grd1.DataKeys[e.Row.DataItemIndex].Value));
rpt.DataBind();
}
}
grd1.DataKeys[e.Row.DataItemIndex].Value line is throwing error. How to handle this to pass values of page 2 only.
Try handling the OnRowDataBound event of the grid. This gives you a GridViewRowEventArgs object (say e).
You can then look at e.Row.DataItem to get the data it is binding to to check if you need to hide the header.
You can use e.Row.FindControl("RepeaterName") to get the repeater to manipulate as you want.

GridView paging inside an UpdatePanel or PlaceHolder components

I'm new to ASP.NET.
Im developing ASP.NET C# web form which creating GridView components dynamically and filling them using the data received from my webservice.
I'm creating these GridView components programmatically in server-side (cs file)- it has to be flexible - 1 GridView and sometimes 10 GridView components.
The problem occurs when I'm trying to add pagination - whenever the user clicks the "next" page, the whole page is getting refreshed because of a postBack and I'm loosing all my data and the page returns Blank/Empty.
I used PlaceHolder to hold the GridView components, while searching for a solution, I found UpdatePanel as a better alternative - as far as I understand the page can be partially refreshed - which means that only the UpdatePanel has to be refreshed...but it doesn't work.
The following code sample is my TEST, the UpdatePanel is the only component initiated in the client side (.aspx page), the rest initiated programmatically in .cs .
how can I solve the issue described above?
Why does the whole page is getting refreshed and I'm loosing my data?
can you recommend another way? can provide me with any code sample?
If I'm not rebuilding the GridView, it doesn't work...
Here is my Default.aspx.cs
public partial class TestAjaxForm : System.Web.UI.Page
{
DataTable table;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
bindGridView();
}
public void bindGridView()
{
GridView gridView1 = new GridView();
gridView1.AutoGenerateColumns = true;
gridView1.PageSize = 2;
gridView1.AllowPaging = true;
gridView1.PagerSettings.Mode = PagerButtons.Numeric;
gridView1.PagerSettings.Position = PagerPosition.Bottom;
gridView1.PagerSettings.PageButtonCount = 10;
gridView1.PageIndexChanging += new GridViewPageEventHandler(this.GridView1_PageIndexChanging);
table = new DataTable();
table.Columns.Add("FirstName");
table.Columns.Add("LastName");
DataRow row = table.NewRow();
row["FirstName"] = "John";
row["LastName"] = "Johnoson";
table.Rows.Add(row);
row = table.NewRow();
row["FirstName"] = "Johnny";
row["LastName"] = "Marley";
table.Rows.Add(row);
row = table.NewRow();
row["FirstName"] = "Kate";
row["LastName"] = "Li";
table.Rows.Add(row);
panel.ContentTemplateContainer.Controls.Add(gridView1);
gridView1.DataSource = table;
gridView1.DataBind();
}
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridView gridView1 = (GridView)sender;
gridView1.PageIndex = e.NewPageIndex;
gridView1.DataSource = table;
gridView1.DataBind();
}
}
Thank you.
If you want a custom GridView approach to work, you have to recreate and rebind the grid on every page load... that's the problem with dynamic Grids... Dynamic controls don't retain their viewstate, but if you added the grid and dynamically generated the columns, that would work easier for you (because I think it may dynamically remember the columns, or you can set AutoGenerateColumns to true, and it brings in your data row column names).
HTH
You should create your GridView and add it to the control tree in the PreInit or Init event handler so that they have a chance to properly bind to ViewState, and it should be done whether or not there's a postback: if you don't add them in a postback, they obviously won't be there to display anything.
DataBinding can happen later in the page life cycle.
Paging only seems to work if you also use an ObjectDataSource; I've never been able to get it to work with a GridView by itself.
I think the easiest thing to do is have the gridview declared in the aspx page inside the place holder, while the place holder is also contained inside the update panel.
For what I can see, John is not doing anything that can't be declared in the markup itself so that shouldn't be a problem. If for some reason the gridview should not be displayed on the screen, it suffices to set the Visible property of the placeholder to false.
As far as paging is concerned, as RickNz correctly points out, it will only retain the state if you bind the gridview to either a LinqDatasource, SqlDatasource or ObjectDatasource but if you bind it to custom business objects, what you need to do is save the data in Session and rebind it again on PageIndexChanged.
In pseudo code, would be sometging like this.
Page_load
{
If (!IsPostBack)
Binddata();
}
private void Binddata()
{
var data = Getdata();
Gridview1.DataSource= data;
Gridview.DataBind();
Session["data"]=data; // cache the data
}
protected void Gridview1_indexchanged(object sender, GridviewPageEventArgs e)
{
var data= Session["data"];
Gridview1. DataSource=data;
Gridview1.DataBind();
GridView1.PageIndex=e.NewPageIndex;
}

Categories

Resources