Reputation: 1149
I want to hide ID column in my GridView, I knew the code
GridView1.Columns[0].Visible = false;
but the surprise was that my count property for my GridView
columns is 0 !!! while I can see data in the GridView
, so any ideas?
Thank you,
Update:
here is the complete code for the method which populate the GridView
public DataSet GetAllPatients()
{
SqlConnection connection = new SqlConnection(this.ConnectionString);
String sql = "SELECT [ID],[Name],[Age],[Phone],[MedicalHistory],[Medication],[Diagnoses] FROM [dbo].[AwadyClinc_PatientTbl]order by ID desc";
SqlCommand command = new SqlCommand(sql, connection);
SqlDataAdapter da = new SqlDataAdapter(command);
DataSet ds = new DataSet();
da.Fill(ds);
return ds;
}
Upvotes: 46
Views: 321375
Reputation: 173
Since you want to hide your column you can always hide the column in preRender event of the gridview . This helps you with reducing one operation for every rowdatabound event per row . You will need only one operation for prerender event .
protected void gvVoucherList_PreRender(object sender, EventArgs e)
{
try
{
int RoleID = Convert.ToInt32(Session["RoleID"]);
switch (RoleID)
{
case 6: gvVoucherList.Columns[11].Visible = false;
break;
case 1: gvVoucherList.Columns[10].Visible = false;
break;
}
if(hideActionColumn == "ActionSM")
{
gvVoucherList.Columns[10].Visible = false;
hideActionColumn = string.Empty;
}
}
catch (Exception Ex)
{
}
}
Upvotes: 0
Reputation: 28
Please use this code. This make invisible column if empty...
protected void gridview1_DataBound(object sender, EventArgs e)
{
Boolean hasData = false;
for (int col = 0; col < gridview1.HeaderRow.Cells.Count; col++)
{
for (int row = 0; row < gridview1.Rows.Count; row++)
{
if (!String.IsNullOrEmpty(gridview1.Rows[row].Cells[col].Text)
&& !String.IsNullOrEmpty(HttpUtility.HtmlDecode(gridview1.Rows[row].Cells[col].Text).Trim()))
{
hasData = true;
break;
}
}
if (!hasData)
{
gridview1.HeaderRow.Cells[col].Visible = false;
for (int hiddenrows = 0; hiddenrows < gridview1.Rows.Count; hiddenrows++)
{
gridview1.Rows[hiddenrows].Cells[col].Visible = false;
}
}
hasData = false;
}
}
Upvotes: 0
Reputation: 1
There is a small change to happen, it will not come under rowdatabound, first all the rows should get bound, only then could we hide that. So it will be a separate method after the grid is dataBound.
Upvotes: 0
Reputation: 4838
What most answers here don't explain is - what if you need to make columns visible again and invisible, all based on data dynamically? After all, shouldn't GridViews
be data centric?
What if you want to turn ON or OFF columns based on your data?
My Gridview
<asp:GridView ID="gvLocationBoard" runat="server" AllowPaging="True" AllowSorting="True" ShowFooter="false" ShowHeader="true" Visible="true" AutoGenerateColumns="false" CellPadding="4" ForeColor="#333333" GridLines="None"
DataSourceID="sdsLocationBoard" OnDataBound="gvLocationBoard_DataBound" OnRowDataBound="gvLocationBoard_RowDataBound" PageSize="15" OnPreRender="gvLocationBoard_PreRender">
<RowStyle BackColor="#F7F6F3" ForeColor="#333333" />
<Columns>
<asp:TemplateField HeaderText="StudentID" SortExpression="StudentID" Visible="False">
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Eval("StudentID") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Student" SortExpression="StudentName">
<ItemTemplate>
<asp:Label ID="Label3" runat="server" Text='<%# Eval("StudentName") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Status" SortExpression="CheckStatusName" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:HiddenField ID="hfStatusID" runat="server" Value='<%# Eval("CheckStatusID") %>' />
<asp:Label ID="Label4" runat="server" Text='<%# Eval("CheckStatusName") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="RollCallPeriod0" Visible="False">
<ItemTemplate>
<asp:CheckBox ID="cbRollCallPeriod0" runat="server" />
<asp:HiddenField ID="hfRollCallPeriod0" runat="server" Value='<%# Eval("RollCallPeriod") %>' />
</ItemTemplate>
<HeaderStyle Font-Size="Small" />
<ItemStyle HorizontalAlign="Center" />
</asp:TemplateField>
<asp:TemplateField HeaderText="RollCallPeriod1" Visible="False">
<ItemTemplate>
<asp:CheckBox ID="cbRollCallPeriod1" runat="server" />
<asp:HiddenField ID="hfRollCallPeriod1" runat="server" Value='<%# Eval("RollCallPeriod") %>' />
</ItemTemplate>
<HeaderStyle Font-Size="Small" />
<ItemStyle HorizontalAlign="Center" />
</asp:TemplateField>
..
etc..
Note the `"RollCallPeriodn", where 'n' is a sequential number.
The way I do it, is to by design hide all columns that I know are going to be ON (visible="true") or OFF (visible="false") later, and depending on my data.
In my case I want to display Period Times up to a certain column. So for example, if today is 9am then I want to show periods 6am, 7am, 8am and 9am, but not 10am, 11am, etc.
On other days I want to show ALL the times. And so on.
So how do we do this?
Why not use PreRender
to "reset" the Gridview
?
protected void gvLocationBoard_PreRender(object sender, EventArgs e)
{
GridView gv = (GridView)sender;
int wsPos = 3;
for (int wsCol = 0; wsCol < 19; wsCol++)
{
gv.Columns[wsCol + wsPos].HeaderText = "RollCallPeriod" + wsCol.ToString("{0,00}");
gv.Columns[wsCol + wsPos].Visible = false;
}
}
Now turn ON the columns you need based on finding the Start of the HeaderText and make the column visible if the header text is not the default.
protected void gvLocationBoard_DataBound(object sender, EventArgs e)
{
//Show the headers for the Period Times directly from sdsRollCallPeriods
DataSourceSelectArguments dss = new DataSourceSelectArguments();
DataView dv = sdsRollCallPeriods.Select(dss) as DataView;
DataTable dt = dv.ToTable() as DataTable;
if (dt != null)
{
int wsPos = 0;
int wsCol = 3; //start of PeriodTimes column in gvLocationBoard
foreach (DataRow dr in dt.Rows)
{
gvLocationBoard.Columns[wsCol + wsPos].HeaderText = dr.ItemArray[1].ToString();
gvLocationBoard.Columns[wsCol + wsPos].Visible = !gvLocationBoard.Columns[wsCol + wsPos].HeaderText.StartsWith("RollCallPeriod");
wsPos += 1;
}
}
}
I won't reveal the SqlDataSource
here, but suffice to say with the PreRender
, I can reset my GridView
and turn ON the columns I want with the headers I want.
So the way it works is that everytime you select a different date or time periods to display as headers, it resets the GridView to the default header text and Visible="false" status before it builds the gridview
again. Otherwise, without the PreRender
, the GridView will have the previous data's headers as the code behind wipes the default settings.
Upvotes: 2
Reputation: 3881
GridView.Columns.Count
will always be 0 when your GridView has its AutoGenerateColumns
property set to true
(default is true
).
You can explicitly declare your columns and set the AutoGenerateColumns
property to false
, or you can use this in your codebehind:
GridView.Rows[0].Cells.Count
to get the column count once your GridView data has been bound, or this:
protected void GridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
e.Row.Cells[index].Visible = false;
}
to set a column invisible using your GridView's RowDataBound
event.
Upvotes: 76
Reputation: 330
This was the code that worked for me when the column Id is unknown and the AutoGenerateColumns == true;
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Drawing" %>
<html>
<head runat="server">
<script runat="server">
protected void Page_Load(object sender, EventArgs eventArgs)
{
DataTable data = new DataTable();
data.Columns.Add("Id", typeof(int));
data.Columns.Add("Notes", typeof(string));
data.Columns.Add("RequestedDate", typeof(DateTime));
for (int idx = 0; idx < 5; idx++)
{
DataRow row = data.NewRow();
row["Id"] = idx;
row["Notes"] = string.Format("Note {0}", idx);
row["RequestedDate"] = DateTime.Now.Subtract(new TimeSpan(idx, 0, 0, 0, 0));
data.Rows.Add(row);
}
listData.DataSource = data;
listData.DataBind();
}
private void GridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
foreach (TableCell tableCell in e.Row.Cells)
{
DataControlFieldCell cell = (DataControlFieldCell)tableCell;
if (cell.ContainingField.HeaderText == "Id")
{
cell.Visible = false;
continue;
}
if (cell.ContainingField.HeaderText == "Notes")
{
cell.Width = 400;
cell.BackColor = Color.Blue;
continue;
}
if (cell.ContainingField.HeaderText == "RequestedDate")
{
cell.Width = 130;
continue;
}
}
}
</script>
</head>
<body>
<form runat="server">
<asp:GridView runat="server" ID="listData" AutoGenerateColumns="True" HorizontalAlign="Left"
PageSize="20" OnRowDataBound="GridView_RowDataBound" EmptyDataText="No Data Available."
Width="95%">
</asp:GridView>
</form>
</body>
</html>
Upvotes: 0
Reputation: 1309
If you want to hide a column by its name instead of its index in GridView. After creating DataTable or Dataset, you have to find the index of the column by its name then save index in global variable like ViewStae, Session and etc and then call it in RowDataBound, like the example:
string headerName = "Id";
DataTable dt = .... ;
for (int i=0;i<dt.Columns.Count;i++)
{
if (dt.Columns[i].ColumnName == headerName)
{
ViewState["CellIndex"] = i;
}
}
... GridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header || e.Row.RowType == DataControlRowType.DataRow || e.Row.RowType == DataControlRowType.Footer)
{
int index = Convert.ToInt32(ViewState["CellIndex"]);
e.Row.Cells[index].Visible = false;
}
}
Upvotes: 2
Reputation: 131
private void Registration_Load(object sender, EventArgs e)
{
//hiding data grid view coloumn
datagridview1.AutoGenerateColumns = true;
datagridview1.DataSource =dataSet;
datagridview1.DataMember = "users"; // users is table name
datagridview1.Columns[0].Visible = false;//hiding 1st coloumn coloumn
datagridview1.Columns[2].Visible = false; hiding 2nd coloumn
datagridview1.Columns[3].Visible = false; hiding 3rd coloumn
//end of hiding datagrid view coloumns
}
}
Upvotes: 2
Reputation: 379
This helped for me
this.myGridview.Columns[0].Visible = false;
Here 0 is the column index i want to hide.
Upvotes: 35
Reputation: 377
You can hide a specific column by querying the datacontrolfield collection for the desired column header text and setting its visibility to true.
((DataControlField)gridView.Columns
.Cast<DataControlField>()
.Where(fld => (fld.HeaderText == "Title"))
.SingleOrDefault()).Visible = false;
Upvotes: 28
Reputation: 1413
Here i am binding the gridview with dataset like this-
GVAnswer.DataSource = DS.Tables[0];
GVAnswer.DataBind();
Then after
Then we count the number of rows like this in the for loop
for (int i = 0; i < GVAnswer.Rows.Count; i++)
{
}
Then after we find the header we want make visible false
GVAnswer.HeaderRow.Cells[2].Visible = false;
then after we make the visibility false of that particular cell.
The complete code is give like this
public void FillGVAnswer(int QuestionID)
{
try
{
OBJClsQuestionAnswer = new ClsQuestionAnswer();
DS = new DataSet();
DS = OBJClsQuestionAnswer.GetAnswers(QuestionID);
GVAnswer.DataSource = DS.Tables[0];
GVAnswer.DataBind();
if (DS.Tables[0].Rows.Count > 0)
{
for (int i = 0; i < GVAnswer.Rows.Count; i++)
{
GVAnswer.HeaderRow.Cells[2].Visible = false;
GVAnswer.HeaderRow.Cells[3].Visible = false;
GVAnswer.HeaderRow.Cells[6].Visible = false;
GVAnswer.HeaderRow.Cells[8].Visible = false;
GVAnswer.HeaderRow.Cells[10].Visible = false;
GVAnswer.HeaderRow.Cells[11].Visible = false;
//GVAnswer.Rows[i].Cells[1].Visible = false;
if (GVAnswer.Rows[i].Cells[4].Text == "T")
{
GVAnswer.Rows[i].Cells[4].Text = "Text";
}
else
{
GVAnswer.Rows[i].Cells[4].Text = "Image";
}
if (GVAnswer.Rows[i].Cells[5].Text == "View Image")
{
HtmlAnchor a = new HtmlAnchor();
a.HRef = "~/ImageHandler.aspx?ACT=AIMG&AID=" + GVAnswer.Rows[i].Cells[2].Text;
a.Attributes.Add("rel", "lightbox");
a.InnerText = GVAnswer.Rows[i].Cells[5].Text;
GVAnswer.Rows[i].Cells[5].Controls.Add(a);
}
if (GVAnswer.Rows[i].Cells[7].Text == "Yes")
{
j++;
ViewState["CheckHasMulAns"] = j;// To Chek How Many answer Of a particulaer Question Is Right
}
GVAnswer.Rows[i].Cells[8].Visible = false;
GVAnswer.Rows[i].Cells[3].Visible = false;
GVAnswer.Rows[i].Cells[10].Visible = false;
GVAnswer.Rows[i].Cells[6].Visible = false;
GVAnswer.Rows[i].Cells[11].Visible = false;
GVAnswer.Rows[i].Cells[2].Visible = false;
}
}
}
catch (Exception ex)
{
string err = ex.Message;
if (ex.InnerException != null)
{
err = err + " :: Inner Exception :- " + ex.InnerException.Message;
}
string addInfo = "Error in getting Answers :: -> ";
ClsExceptionPublisher objPub = new ClsExceptionPublisher();
objPub.Publish(err, addInfo);
}
}
Upvotes: 3
Reputation: 2080
Some of the answers I've seen explain how to make the contents of a cell invisible, but not how to hide the entire column, which is what I wanted to do.
If you have AutoGenerateColumns = "false"
and are actually using BoundField
for the column you want to hide, Bala's answer is slick. But if you are using TemplateField
for the column, you can handle the DataBound
event and do something like this:
protected void gridView_DataBound(object sender, EventArgs e)
{
const int countriesColumnIndex = 4;
if (someCondition == true)
{
// Hide the Countries column
this.gridView.Columns[countriesColumnIndex].Visible = false;
}
}
This may not be what the OP was looking for, but it's the solution I was looking for when I found myself asking the same question.
Upvotes: 13
Reputation: 1476
If you wanna hide that column while grid populating, you can do it in aspx page itself like this
<asp:BoundField DataField="test" HeaderText="test" Visible="False" />
Upvotes: 2