How to check for an Empty Gridview - c#

I have an ASP.NET 2.0 (C#) web app, and in it I have a gridview that gets its data from an oracle database.
I want to know how to check if the gridview is empty, and the do something.
I have already tried:
if(GridView.Rows.Count == 0)
{
// Do Something
}
but it doesn't work...
Any ideas?
Thank you.

Your code should work. But only after GridView.DataBind() has been called. Generally I don't check the GridView it's self, but the datasource of the grid view.
DataTable data = DAL.getdata();
if (data.Rows.Count == 0)
{
ShowEmptyData();
}
else
{
Grid.DataSource = dt;
Grid.DataBind();
}

This doesn't work since the GridView is data bound and is going to fetch the actual data at a later time while rendering the page. You should check this by directly querying the data binding source of the gridview (see if the actual list that's grid view bound to is empty or not).
If you just want to display something when it's empty, you should use <EmptyDataTemplate> in your markup:
<asp:GridView runat="server">
<EmptyDataTemplate>The grid is empty</EmptyDataTemplate>
</asp:GridView>

I agree with the other responses. I want to add little information, you should get rows.count after databind method :
int rowCount = GridView.Rows.Count; // returns zero
GridView.DataBind();
rowCount = GridView.Rows.Count; // returns actual row count

If you're using databinding, the the row count of the datasource not the count on the grid itself.

Its very easy: Hope it works for you.. :)
Use event of GridView DataBound: which fires after data is bound.
protected void GridView1_DataBound(object sender, EventArgs e)
{
int rowCount = GridView1.Rows.Count;
if (rowCount == 0)
{
GridView1.Visible = false;
}
else
{
GridView1.Visible = true;
}
}

First create a helper class.
public static class GridViewExtensions
{
public static IEnumerable<GridViewRow> AsEnumerable(this GridView grid)
{
foreach (GridViewRow row in grid.Rows)
{
yield return row;
}
}
public static bool IsEmpty(this GridView grid)
{
return !grid.AsEnumerable().Any(t => t.RowType == DataControlRowType.DataRow);
}
}
Then just call IsEmpty
GridView1.IsEmpty()

In case you've configured your GV to automatically fetch the data from DB, then you may add the following line as the first statement of your GV in Source mode:
<EmptyDataTemplate>No data found.</EmptyDataTemplate>
And then continue with the normal code in your GV.

Based on answers already, GridView.Rows.Count is not enough on its own, depending on the nature of your GridView, especially if it's a dynamic gv, which in most cases it is, plus you have to factor in Paginating, Headers and Footers, which alter the row count.
I use a simple method to tell me ...
//checks if a gridview has any actual rows of data (not just blank rows filled in by the Load
protected bool gvNoData(GridView gv)
{
int wsDataRow = 0;
foreach (GridViewRow gvRow in gv.Rows)
if (gvRow.RowType == DataControlRowType.DataRow)
{
HiddenField hf = (HiddenField)gvRow.FindControl("hfStudentID");
if (hf != null)
if (hf.Value.ToString().Length > 0)
wsDataRow +=1;
}
//if a count was generated then there are data rows, otherwise the rows are blank or nonexistant
if (wsDataRow > 0) return false;
else return true;
}
So running something like this will tell you if the Rows are really "
"DATA" rows, or empty or nothing!
Obviously in my case I have a HiddenField to tell me if the GridViewRow is an actual data row, as I prefill my gridview with blank rows (for my purposes) and some datarows.
However, a simpler version to check based on DataRow vs HeaderRow, etc...
foreach (GridViewRow gvRow in myGridView.Rows)
if (gvRow.RowType == DataControlRowType.DataRow)
{
//do what you need
}
I hope this helps.
In short, there is no GridView.IsEmpty() function unfortunately, unless you enumerate one as shown below.

Related

ASP.NET How do I check ever row in the gridview?

I want to add value into a Grid view via dropdownlist with a button.
I want the ddTN.SelectedItem.value in the Grid view to be unique. No duplication
How do I check every row for the ddTN.SelectedItem.value before adding a new ddTN.SelectedItem.value into the Grid view?
This are the codes that I have and it keep comparing the value with the first value in the gridview. Not the others.
I don't want to use a checkbox and such. All the example I found required using checkbox.
protected void Insert(object sender, EventArgs e)
{
int i = 0;
var p = 1;
DataControlFieldCell cell = GridView1.Rows[i].Cells[p] as DataControlFieldCell;
if (cell.Text != ddTN.SelectedItem.Value)
{
dt.Rows.Add(ddTN.SelectedValue, ddDuration.SelectedValue);
ViewState["Customers"] = dt;
this.BindGrid();
label.Text = "";
p++;
}
else
{
label.Text = "Exercise already inserted";
}
}
It looks like you were intending on looping over the items in the grid but you have forgotten the looping mechanism. In your code, it always only checks the first item because i is initialized to 0 and never changes.
Try using a looping mechanism like a for loop or a while loop. Or, if you know the items in the grid from the beginning, perhaps use a hash table for quickly checking if the selected item already exists.
Keep trying, you are almost there!

Hiding a GridView ID column

Seems to be a common issue.
I'm trying to hide a column of my GridView. I have read that simply setting the column to 'visible = false' will not work as I'm auto-generating my data.
Currently my code stands as so:
protected void Page_Load(object sender, EventArgs e)
{
bind();
if (GridView1.Columns.Count > 0)
GridView1.Columns[0].Visible = false;
else
{
GridView1.HeaderRow.Cells[0].Visible = false;
foreach (GridViewRow gvr in GridView1.Rows)
{
gvr.Cells[1].Visible = false;
}
}
}
The 'if' statement will not trigger as as said I am auto-generating the data. With the above loop, I can hide the header text of the column but want to hide the whole column with the ability to still be able to access the hidden data.
How about just doing this later in the control's life cycle (when the Columns collection has been populated):
protected void GridView1_PreRender(object sender, EventArgs e)
{
if (GridView1.Columns.Count > 0)
GridView1.Columns[0].Visible = false;
else
{
GridView1.HeaderRow.Cells[0].Visible = false;
foreach (GridViewRow gvr in GridView1.Rows)
{
gvr.Cells[1].Visible = false;
}
}
}
Note: you would need to add OnPreRender="GridView1_PreRender" to your GridView markup.
Why not use the GridView.DataKeyNames and GridView.DataKeys properties to store the ID and then retrieve it with the rowIndex later? This also will keep the column from being autogenerated.
DataKeyNames
DataKeys
This is a limitation with auto-generating columns. You give up a lot of control over HOW the columns are displayed for the convenience of not pre-defining them.
Bite the bullet now and define your columns. If this is the ONLY customization you need to make, you may be all right, but 90+% of the time I end up defining columns to customize how they are displayed.
Otherwise you're going to end up with several of these "tweaks" that are prone to breaking under various circumstances (e.g. the order of the columns changes in the data source).
Ah... so the problem is the Columns is not predefined.
Perhaps you could use Linq to select all the columns you want to display:
gvTest.DataSource = (from d in dataSource
select new
{
ColumnA = d.ColumnA...
}
Alternatively, you could hide the columns with JavaScript;

how this code (or project) work?(editable ASP Gridview)

I am new in ASP.NET ,I would have editable gridview in asp.net using C# , I found this editable gridview (Database , Project) in codeproject but i didn't realize how
its work specially this part of code:`
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
DataRowView drv = e.Row.DataItem as DataRowView;
if (e.Row.RowType == DataControlRowType.DataRow)
{
if ((e.Row.RowState & DataControlRowState.Edit) > 0)
{
DropDownList dp= (DropDownList )e.Row .FindControl ("DropDownList1");
DataTable dt = load_department();
for (int i = 0; i < dt.Rows.Count; i++)
{
ListItem lt = new ListItem();
lt.Text = dt.Rows[i][0].ToString();
dp.Items.Add(lt);
}
dp.SelectedValue = drv[3].ToString();
RadioButtonList rbtnl = (RadioButtonList)e.Row.FindControl("RadioButtonList1");
rbtnl.SelectedValue = drv[5].ToString();
CheckBoxList chkb = (CheckBoxList)e.Row.FindControl("CheckBoxList2");
chkb.SelectedValue = drv[6].ToString();
}
}
}
`
Why she/he do this??
RowDataBound event fires when you bind the grid to a datasource, say, for example, a datatable.
For each row in the datatable, this code will run, and will, depending on the values in that row, put a value in each column of the grid view.
FindControl is used to find the control with the spcific name on that line of the grid view - remember, it will be repeated many times for as many rows as you have.
Once the control has been found, the value is set.
You are effectively setting up each row of the grid view for each row of the data in your data source.
Take a look at http://msdn.microsoft.com/en-us/magazine/cc163933.aspx for an overview of the intent behind this control.
** RowDataBound Occurs when a data row is bound to data in a GridView control.
**DataControlRowState Specifies the state of a row in a data control for eg.Edit,Insert,Selected etc
** RowState Gets the current state of the row with regard to its relationship to the DataRowCollection.
now in that if condition your dropdownbox (DropDownList1) is filled and RadioButton and Checkebox are setting up their selected values.

Question about checkbox and datagridview

I have datagridview with checkbox column, and the checkbox within the column can be checked or unchecked with external checkbox. It works fine while selecting all the columns and saving the data in database. But, when I unchecked the checkbox in the datagridview with external checkbox and again select the single checkbox within the datagridview, it again takes the rowindex of all the checkbox within the column.
if (chkbranches.Checked == true)
{
foreach (DataGridViewRow dr in gridviewholiday.Rows)
{
dr.Cells[0].Value = true;
}
for (int i = 0; i < gridviewholiday.Rows.Count; i++)
{
rowindex = i;
list.add(rowindex);//to put the rowindex in array list
}
}
else if (chkbranches.Checked == false)
{
foreach (DataGridViewRow dr in gridviewholiday.Rows)
{
dr.Cells[0].Value = false;
gridviewholiday.Refresh();
gridviewholiday.ClearSelection();
list.Clear();
}
}
Why do you loop twice if chkbranches is checked? Can't you add items to the list within the first foreach? And in the loop for unchecking, why do you refresh, and clear both controls each time? Probably only needed once.
And as mentioned, this isn't doing anything about single checks. If you're expecting it to, that seems to be the problem.
Not quite sure what your attempting to do, but I have something similar with a button that deletes all the checked rows. I use a template field like so for the check box:
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="cbSelector" runat="server" />
</ItemTemplate>
</asp:TemplateField>
Then for the Delete button code behind I do:
protected void btnDeleteChecked_Click(object sender, EventArgs e)
{
foreach (GridViewRow row in gridOrders.Rows)
{
CheckBox cb = (CheckBox)row.FindControl("cbSelector");
if ((null != cb) && cb.Checked)
{
uint id = Convert.ToUInt32(gridOrders.DataKeys[row.RowIndex].Value);
gInvoiceDB.DeleteInvoice(id, true);
}
}
}

C# dynamically taking data from DataGridView

I'm trying to get my current program to take information from a dynamically created DataGridView. I have managed to get the information into the grid, and perform the required search, however now I'm really stuck.
I have added a column to the datagridview which holds a button within each row. What I'd like to do is take the value of the data from column index 1 which is in the same row as the button clicked. Confusing? Anyway, here's the code:
public void GetValues(...)
{
//Details regarding connection, querying and inserting table
.
.
.
DataGridViewButtonColumn buttonCol = new DataGridViewButtonColumn();
buttonCol.Name = "ButtonColumn";
buttonCol.HeaderText = "Select";
buttonCol.Text = "Edit";
//NB: the text won't show up on the button. Any help there either?
dataGridView1.Columns.Add(buttonCol);
dataGridView1.CellClick += new DataGridViewCellEventHandler(dataGridView1_CellClick);
foreach (DataGridViewRow row in dataGridView1.Rows)
{
DataGridViewButtonCell button = (row.Cells["ButtonColumn"] as DataGridViewButtonCell);
}
dataGridView1.Columns["ButtonColumn"].DisplayIndex = 0;
}
void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
//Here is where I'm having the trouble. What do I put in here???
}
Thanks for any help you can give!
David.
Your DataGridViewCellEventArgs contains very useful information such as RowIndex.
So something like (I don't know what you want to do with the value):
String dataYouWant = dataGridView1.Rows[e.RowIndex].Cells[1].Value;
`
if (e.ColumnIndex != button_column_number) //column number of the button.
return;
dataGridView1.EndEdit();
bool val;
if ((dataGridView1.Rows[e.RowIndex].Cells[1].Value) != null) // column index 1...as that's what you want.
{
//d stuff you want here.
}
else
{
}
`

Categories