Hiding Columns in Gridview when grid view is empty - asp.net

I have a grid view on which i am hiding some columns. it gives me expected result when there is at least one item in grid view but when my grid is empty then it shows hidden columns. what to do how to solve it when there is no record means grid view is empty then it also hides the columns that has been made hidden i am hiding columns in OnitemDataBound(object sender, GridItemEventArgs e) event of grid.

Put the Hidden column data in DatakeysName property of Gridview. Then it will not show any column. You can get that for further use. If you want to show no data found message, then set EmptyDataText="No Data Found!!!".

Assuming that if there is no data coming from the server you want to hide the column names or something like that. You can use empty template feature of grid view. Go to the designer mode click quick property of grid view. Go to the templates and select the empty template. Then write some text or message like "No record found." and run the code. You do not need to write any server side code for this.

The Column should be made hidden using the code.
1. The logic should be such that we loop through the rows and see if the column does not have values for all the rows.
2. if the value does not exist for the column only then make the column hidden.
3. this entire logic should be implemented in prerender event.
I can provide you sample code tonight...
here is the sample code...
protected void GridView1_PreRender(object sender, EventArgs e)
{
bool isColumnEmpty = true;
int columnIndex =2;
for (int i = 0; i < GridView1.Rows.Count; i++)
{
if (GridView1.Rows[i].Cells[columnIndex].ToString() != string.Empty)
{
isColumnEmpty = false;
break;
}
}
if (isColumnEmpty)
{
GridView1.Columns[columnIndex].Visible = false;
}
}
Full Code Sample
ASPX Code :
<form id="form1" runat="server">
<div>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
onprerender="GridView1_PreRender">
<Columns>
<asp:BoundField DataField="dc1" HeaderText="Column - 1" />
<asp:BoundField DataField="dc2" HeaderText="Column - 2" />
<asp:BoundField DataField="dc3" HeaderText="Column - 3" />
<asp:BoundField DataField="dc4" HeaderText="Column - 4" />
<asp:BoundField DataField="dc5" HeaderText="Column - 5" />
</Columns>
</asp:GridView>
</div>
</form>
CS Code :
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
GridView1.DataSource = GetDataSet();
GridView1.DataBind();
}
private DataSet GetDataSet()
{
DataSet ds = new DataSet();
DataTable dt = new DataTable();
DataColumn dc1 = new DataColumn("dc1");
DataColumn dc2 = new DataColumn("dc2");
DataColumn dc3 = new DataColumn("dc3");
DataColumn dc4 = new DataColumn("dc4");
DataColumn dc5 = new DataColumn("dc5");
dt.Columns.Add(dc1);
dt.Columns.Add(dc2);
dt.Columns.Add(dc3);
dt.Columns.Add(dc4);
dt.Columns.Add(dc5);
for (int i = 0; i < 10; i++)
{
DataRow dr = dt.NewRow();
dr[dc1] = i;
//dr[dc2] = "2" + i.ToString();
dr[dc3] = "3"+ i.ToString();
dr[dc4] = "4" + i.ToString();
dr[dc5] = "5" + i.ToString();
dt.Rows.Add(dr);
}
ds.Tables.Add(dt);
return ds;
}
protected void GridView1_PreRender(object sender, EventArgs e)
{
bool isColumnEmpty = true;
int columnIndex =2;
for (int i = 0; i < GridView1.Rows.Count; i++)
{
if (GridView1.Rows[i].Cells[columnIndex].ToString() != string.Empty)
{
isColumnEmpty = false;
break;
}
}
if (isColumnEmpty)
{
GridView1.Columns[columnIndex].Visible = false;
}
}
}

Related

How to determine which button is clicked in dynamically created DataTable

I'm creating dynamically data Table bound to Grid View. Every row is populated with button. When i determine which button is clicked on the row, i want to get the current value of cell in clicked button in that row and modify her.Help!
Markup
<asp:GridView ID="GridView2" runat="server"
OnRowDataBound="GridView2_RowDataBound">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="btnTest" runat="server"
CommandName="odzemi"
CssClass="button2"
Font-Bold="True"
Text="-"
Width="100px"
OnClick="btnTest_Click" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
//in this way a create row
private void AddNewRecordRowToGrid()
{
int counter;
if (Request.Cookies["kasa"] == null)
counter = 0;
else
{
counter = int.Parse(Request.Cookies["kasa"].Value);
}
counter++;
Response.Cookies["kasa"].Value = counter.ToString();
Response.Cookies["kasa"].Expires = DateTime.Now.AddYears(2);
if (ViewState["Markici"] != null)
{
DataTable dtCurrentTable = (DataTable)ViewState["Markici"];
DataRow drCurrentRow = null;
if (dtCurrentTable.Rows.Count > 0)
{
for (int i = 1; i <= dtCurrentTable.Rows.Count; i++)
{
HttpCookie cookie = Request.Cookies["Democookie"];
drCurrentRow = dtCurrentTable.NewRow();
drCurrentRow["FirmaID"] = Request.Cookies["firma"].Value;
drCurrentRow["Godina"] = Request.Cookies["godina"].Value;
drCurrentRow["KasaID"] = Request.Cookies["kasa"].Value;
drCurrentRow["MarkicaID"] = Request.Cookies["kasa"].Value;
drCurrentRow["Datum"] = DateTime.Now;
drCurrentRow["Masa"] = Session["masa39"];
drCurrentRow["VrabotenID"] = Session["New"];
drCurrentRow["Artikal"] = Label3.Text;
drCurrentRow["Cena1"] = Label4.Text;
//this is where i need to make changes
drCurrentRow["Kolicina"] = Label5.text;
drCurrentRow["Smena"] = Session["smena1"];
drCurrentRow["VkIznos"] = Label6.Text;
drCurrentRow["VkDanok"] = Label8.Text;
drCurrentRow["SySDatum"] = DateTime.Now;
drCurrentRow["Vid"] = Label23.Text;
drCurrentRow["Edmera"] = Label10.Text;
drCurrentRow["ArtikalID"] = Label33.Text;
}
//Removing initial blank row
if (dtCurrentTable.Rows[0][0].ToString() == "")
{
dtCurrentTable.Rows[0].Delete();
dtCurrentTable.AcceptChanges();
}
//Added New Record to the DataTable
dtCurrentTable.Rows.InsertAt(drCurrentRow,0);
//storing DataTable to ViewState
ViewState["Markici"] = dtCurrentTable;
//binding Gridview with New Row
GridView2.DataSource = dtCurrentTable;
GridView2.DataBind();
}
}
}
//in this button i call that method
protected void Button9_Click(object sender, EventArgs e)
{
AddNewRecordRowToGrid();
}
//
and here i'm determine clicked button of row, and here in this
dtCurrentTable.Rows[clickedIndex]["Kolicina"]= "" i need to
get cureent value of cell which is different in every row.
protected void btnTest_Click(object sender, EventArgs e)
{
DataTable dtCurrentTable = (DataTable)ViewState["Markici"];
var clickedRow = ((Button)sender).NamingContainer as GridViewRow;
var clickedIndex = clickedRow.RowIndex;
//so here i want to get current value of cell, and modify her
dtCurrentTable.Rows[clickedIndex]["Kolicina"] = " ";
GridView2.DataSource = dtCurrentTable;
GridView2.DataBind();
}
Try this.
protected void btnTest_Click(object sender, EventArgs e)
{
var clickedRow = ((Button)sender).NamingContainer as GridViewRow;
var clickedIndex = clickedRow.RowIndex;
}
Provided your GridView does not have sorting or paging enabled, from this clickedIndex, we can get the corresponding Row of the DataTable like this.
dtCurrentTable.Rows[clickedIndex]["Kolicina"] = "StackOverflow";
In the RowDataBound event, the EventArgument e should have the index of the current item bound in it. The code e.Row.RowIndex will return the index of the row in the Grid, not necessarily the datasource when you have paging applied. There is a 'DataItemIndex' property, another index that may give you what you are looking for, depending on what you are trying to do.
The grid also exposes the Rows collection, which you can use a foreach to loop through each one, and access that way too.
Note, the Rows on postback will only be based on the markup posted back through viewstate; the grid knows nothing about your data source (unless you rebind on every postback).

GridView dynamic Controls are emptied upon clicking edit/update/delete buttons. Asp.net

I have a gridview that is being dynamically populated using a custom template, but the command fields are static. Upon clicking the command fields, the controls are understandably lost. This problem doesn't affect me during edit, because once the gridview is rebound, it would know it is in edit mode and create the dynamic edit template fields. But once I make changes to these fields, which are textboxes, I would need to click on the Update command field to instantiate my update method. Upon clicking, the controls are immediately lost, so in my update method I cannot find the controls to which changes have been made. Any ideas how to solve this? I will post code if needed.
The Grid View Template. Here is where the databindings happen upon dynamic generation. Getting the data from the table and reproducing it on the grid view works fine.
public class GridViewTemplate : System.Web.UI.Control, System.Web.UI.ITemplate
{
// static attributes here
// constructor
public GridViewTemplate(DataControlRowType type, string columnName, string categoryID, string itemControl, string editControl, string footerControl, string dataBinds)
{
DataRowType = type; // Header, DataRow,
st_columnName = columnName; // Header name
st_categoryId = categoryID;
if (itemControl != null)
st_itemControl = itemControl.ToUpper(); // Control type for Item Template
if (editControl != null)
st_editControl = editControl.ToUpper(); // Control type for Edit Template
if (footerControl != null)
st_footerControl = footerControl.ToUpper(); // Control type for Footer Template
if (dataBinds != null)
st_dataBinds = dataBinds;
}
public void InstantiateIn(Control container)
{
switch (DataRowType)
{
case DataControlRowType.Header:
{
// Build the header for this column
Label lb_header = new Label();
lb_header.Text = "<b>" + st_columnName + "</b>";
lb_header.ID = st_categoryId;
container.Controls.Add(lb_header);
}
break;
case DataControlRowType.DataRow:
{
if (Regex.IsMatch(st_categoryId,"^(xxI_)")) // item mode
{
if (st_itemControl.Equals(LABEL))
{
// For Label
}
else if (st_itemControl.Equals(TEXTBOX))
{
TextBox dcrt_textbox = new TextBox();
dcrt_textbox.ID = st_categoryId;
dcrt_textbox.Visible = true;
dcrt_textbox.Enabled = false;
dcrt_textbox.DataBinding += new EventHandler(this.TextBox_DataBinding);
container.Controls.Add(dcrt_textbox);
}
else if (st_itemControl.Equals(CHECKBOX))
{
// For checkbox
}
}
else if (Regex.IsMatch(st_categoryId, "^(xxE_)")) // edit mode
{
if (st_editControl.Equals(LABEL))
{
// For label
}
else if (st_editControl.Equals(TEXTBOX))
{
TextBox dcrt_textbox = new TextBox();
dcrt_textbox.ID = st_categoryId;
dcrt_textbox.Visible = true;
dcrt_textbox.EnableViewState = true;
dcrt_textbox.AutoPostBack = false;
dcrt_textbox.ViewStateMode = ViewStateMode.Enabled;
dcrt_textbox.DataBinding += new EventHandler(this.TextBox_DataBinding);
container.Controls.Add(dcrt_textbox);
}
else if (st_editControl.Equals(CHECKBOX))
{
// For checkbox
}
}
}
break;
case DataControlRowType.EmptyDataRow:
// To be implemented when necessary
break;
case DataControlRowType.Pager:
// To be implemented when necessary
break;
case DataControlRowType.Separator:
// To be implemented when necessary
break;
default:
break;
}
}
public void TextBox_DataBinding(Object sender, EventArgs e)
{
TextBox tb_databound = (TextBox)sender;
GridViewRow row = (GridViewRow)tb_databound.NamingContainer;
string RawValue = DataBinder.Eval(row.DataItem, st_columnName).ToString();
tb_databound.Text = RawValue;
}
public void Label_DataBinding(Object sender, EventArgs e)
{
Label lb_databound = (Label)sender;
GridViewRow row = (GridViewRow)lb_databound.NamingContainer;
string RawValue = DataBinder.Eval(row.DataItem, st_columnName).ToString();
lb_databound.Text = RawValue;
}
public void CheckBox_DataBinding(Object sender, EventArgs e)
{
CheckBox cb_databound = (CheckBox)sender; // get the control that raised this event
GridViewRow row = (GridViewRow)cb_databound.NamingContainer; // get the containing row
string RawValue = DataBinder.Eval(row.DataItem, st_columnName).ToString();
if (RawValue.ToUpper().Equals("TRUE"))
{
cb_databound.Checked = true;
}
else
{
cb_databound.Checked = false;
}
}
}
}
The onEdit and onUpdate methods.
protected void onRowEditing(object sender, GridViewEditEventArgs e)
{
gv.EditIndex = e.NewEditIndex;
tableBind(ViewState["table"]); // View state contains the table, which is then passed to a bind method that binds the gridview.
}
protected void onRowUpdating(object sender, GridViewUpdateEventArgs e)
{
GridViewRow row = gv_rebateTable.Rows[e.RowIndex];
// at this point, xxE_tier (a textbox in edit mode) was destroyed
TextBox tb = row.FindControl("xxE_tier") as TextBox;
}
Gridview:
<asp:GridView ID="gv" EnableViewState="true" ViewStateMode="Enabled" OnRowEditing="onRowEditing" OnRowCancelingEdit="onRowCancelingEdit" OnRowUpdating="onRowUpdating" OnRowDeleting="onRowDeleting" EnableModelValidation="true" ShowFooter="true" OnRowCommand="onRowCommand" AutoGenerateColumns="False" runat="server">
<Columns>
<asp:ButtonField Text="Analysis" ButtonType="Button" HeaderText="" ShowHeader="True" />
<asp:CommandField EditText="Edit" ButtonType="Button" HeaderText="" ShowEditButton="True" ShowHeader="True" ValidationGroup="Edit_Group"/>
<asp:CommandField EditText="Delete" ButtonType="Button" HeaderText="" ShowDeleteButton="True" ShowHeader="True" />
</Columns>
</asp:GridView>

Populating a list box with text AND value, ASP.Net

I am wanting to know if there is a way to populate a list box with both text and value. The text bit is easy, but I want a value so I can have a user select something in it then press a button which gets the chosen value and uses an SQL query to do the rest.
My code so far for populating the text is:
listAllLessons.Items.Add(detail);
It runs in a loop and is populated from a database.
Thanks
You can do this in Web Forms:
HTML Side:
<asp:DropDownList ID="ddlList"
runat="server" />
<br />
<asp:Button ID="btnSubmit"
runat="server"
OnClick="btnSubmit_Click"
Text="Click Me" />
Code Behind:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//Generate 20 items
foreach(var count in Enumerable.Range(1, 20))
{
var newItem = new ListItem();
newItem.Value = count.ToString();
newItem.Text = "Item " + count.ToString();
ddlList.Items.Add(newItem);
}
}
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
//Gets the selected value
var selectedValue = ddlList.SelectedValue;
System.Diagnostics.Debugger.Break();
}
Have you tried concatenating the items just like this:
while (reader.Read())
{
ListBox1.Items.Add(reader[0].ToString() + "\t" + reader[1].ToString());
}
Please try this:
while (reader.Read())
{
ListItem li = new ListItem(Convert.ToString(reader["test"]), Convert.ToString(reader["value"]));
ListBox1.Items.Add(li);
}
This worked for me.
dt = db.GetAllEmployeeForManagement();
foreach (DataRow item in dt.Rows)
{
ListItem li = new ListItem(Convert.ToString(item["Name"]), Convert.ToString(item["EmployeeID"]));
if (!ListBox1.Items.Equals(li.Text))
{
ListBox1.Items.Add(li);
}
}
where dt is actually a ref name of Datasource so.. it is quite simple!

How to add dynamic n checkbox columns to gridview ASP.NET

Ex: mypage.aspx?num=xxx
How can I add a num checkbox column to Gridview in mypages by code-behind?
I had added num columns to Datatable with parameter typeof(bool) but when I loaded mypage, the checkboxes were disabled so I can't check them.
This is my grid aspx code
<asp:GridView ID="gv" runat="server" AutoGenerateColumns="false">
<Columns>
</Columns>
</asp:GridView>
First of all add num number of template fields to your gridview
protected void Page_PreInit(object sender, EventArgs e)
{
int num = Request.QueryString["num"];
for (int i = 0; i < num; i++)
{
TemplateField tf = new TemplateField();
tf.HeaderText = "Status";
gv.Columns.Add(tf);
}
}
After adding template feilds, now we will add checkboxes to the gridview. We write a function to add checkboxes. Below is the code
private void AddCheckBox()
{
int num = Request.QueryString["num"];
for (int i = 0; i < num; i++)
{
foreach (GridViewRow row in gv.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
CheckBox cb = new CheckBox();
cb.Checked = true;
row.Cells[i].Controls.Add(cb);
}
}
}
}
Now place this function in your grid databound event.
protected void gv_DataBound(object sender, EventArgs e)
{
AddCheckBox();
}
At the end also call the function in the page load event so first time when grid loads it shows checkboxes are checked
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
AddCheckBox();
}
}
To check my code:
I add a bound feild to grid view and bind the grid view with a datatable:
<asp:GridView ID="gv" runat="server" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="Data" HeaderText="Data" />
</Columns>
</asp:GridView>
and in code behind in page_load event i add the following code
DataTable dt = new DataTable();
dt.Columns.Add("Data");
DataRow dr = dt.NewRow();
dr[0] = "Test";
dt.Rows.Add(dr);
gv.DataSource = dt;
gv.DataBind();
and also made 1 change in the function AddCheckBox as
for (int i = 1; i < num + 1; i++)
The above change is made because I have a databound feild at index 0 of the grid view columns so I changed it to start from 1.
and here is the result ( page output )
Data Status Status Status Status Status Status Status Status Status Status
Test Checked Checked Checked Checked Checked Checked Checked Checked Checked Checked
Checked is used for checkbox is checked
Use:
Request.QueryString["num"]
to get the value of num in the URL. Then iterate num times, adding a CheckBoxField to your GridView each time.

Event problem inside grid view with custom paging

I want to provide custom paging in grid view.
<asp:GridView ID="gvFirst" runat="server" AutoGenerateColumns="false"
AllowPaging="true"
ondatabound="gvFirst_DataBound" >
<Columns>
<asp:BoundField DataField="ID" HeaderText="ProductID"/>
<asp:BoundField DataField="Name" HeaderText="ProductName" />
</Columns>
<PagerTemplate>
<asp:Panel ID="pnlPager" runat="server">
</asp:Panel>
</PagerTemplate>
</asp:GridView>
If I create button here and bind click event then it is fire, but problem is this event occur for each row bind with grid
protected void gvFirst_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Pager)
{
Panel pnPager = e.Row.FindControl("pnlPager") as Panel;
if (pnPager != null)
{
Button btnFirst = new Button();
btnFirst.Text = "1";
btnFirst.Click += new EventHandler(btnFirst_Click);
pnPager.Controls.Add(btnFirst);
}
}
}
If I create button here and bind click event then it is not fire; this event fire after all the rows bind to grid, so it will occur only once.
protected void gvFirst_DataBound(object sender, EventArgs e)
{
GridViewRow gvRow = gvFirst.BottomPagerRow;
if (gvRow != null)
{
Panel pnPager = gvRow.FindControl("pnlPager") as Panel;
if (pnPager != null)
{
Button btnFirst = new Button();
btnFirst.Text = "1";
btnFirst.Click += new EventHandler(btnFirst_Click);
pnPager.Controls.Add(btnFirst);
}
}
}
void btnFirst_Click(object sender, EventArgs e)
{
using (_NorthWindDataContext = new NorthWindDataContext())
{
var ProductInformation = from p in _NorthWindDataContext.Products
select new
{
ID = p.ProductID,
Name = p.ProductName
};
gvFirst.DataSource = ProductInformation.Skip(5).Take(5);
gvFirst.DataBind();
}
}
Another problem which I am facing is I want to provide custom paging. Now I have set page size to 5 and I am fetching 5 record from query so my grid pager is not display.
public class Productinformation
{
public int PID
{
get;
set;
}
public string PName
{
get;
set;
}
}
using (NorthWindDataContext _NorthWindDataContext = new NorthWindDataContext())
{
Proinfo = new List<Productinformation>();
Proinfo = (from p in _NorthWindDataContext.Products
select new Productinformation
{
PID = p.ProductID,
PName = p.ProductName,
}).ToList();
gvFirst.DataSource = Proinfo.Take(PageSize) ;
gvFirst.DataBind();
}
Proinfo variable declare globally.
Now when I bind I run this code it will give me error the data source does not support server-side data paging. If I use var type of variable then it is worked but we can't declare var type of variable globally, so I used it then I have to call this method every time in paging, and I don't want to use Objectdatasource.
GridView's RowCreated indeed will be called for every row in GridView, because that is the event where the GridView will (re)create the GridViewRows. But if you check for if (e.Row.RowType == DataControlRowType.Pager) there will be no overhead. This event is perfect for creating dynamic controls because it's called even on postback(as against RowDataBound). So your first way should be the correct one.
If you want to show the pager also when there are less than PageSize rows, you should force the pager to be visible e.g. in GridView's overridden OnPreRender.
GridViewRow pagerRow = (GridViewRow) this.BottomPagerRow;
if(pagerRow != null) pagerRow.Visible = true;

Resources