Conditional Hide GridView Template Column - c#

I'm trying to conditionally hide a template column within the Gridview, I've tried the following, but this doesn't work. Is there a way to do this within the .aspx?
<asp:TemplateField HeaderText="Grade" SortExpression="grade" Visible='<%# Convert.ToDouble(Eval("grade")) == 0 ? true : false %>'>
<ItemTemplate>
<%# string.Format("{0:0.#}", Convert.ToDouble(Eval("grade"))) %>
</ItemTemplate>
</asp:TemplateField>

you can do all of your conditional formatting (colors, hide etc.) by using the itemDataBound event. However, your sample markup does not seem to have a control - and you want to have a control for that information. And that control should have some kind of "id" or name that you can refernce in code.
However, since you did not provide much of the markup? Then I give a example for both the cells collection, and the controls that you might have.
So, say we have this simple grid view. Note how the last two fields are both City, one is a bound field (often common), and the other is a label (but could be a text box or just about any asp.net control).
<asp:GridView ID="GridView1" runat="server" CssClass="table-hover" AutoGenerateColumns="False" DataKeyNames="ID">
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" InsertVisible="False" ReadOnly="True" SortExpression="ID" />
<asp:BoundField DataField="FirstName" HeaderText="FirstName" SortExpression="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" SortExpression="LastName" />
<asp:BoundField DataField="HotelName" HeaderText="HotelName" SortExpression="HotelName" />
<asp:BoundField DataField="City" HeaderText="City" SortExpression="City" />
<asp:TemplateField HeaderText ="City2">
<ItemTemplate>
<asp:Label ID="lblCity" runat="server" Text = '<%# Eval("City") %>' >'<"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Ok, on page load, we load up the above grid with this code:
protected void Page_Load(object sender, System.EventArgs e)
{
if (IsPostBack == false)
LoadGrid();
}
public void LoadGrid()
{
using (SqlCommand cmdSQL = new SqlCommand("SELECT ID, FirstName, LastName, HotelName, City from tblHotels", new SqlConnection(My.Settings.TEST3)))
{
cmdSQL.Connection.Open();
GridView1.DataSource = cmdSQL.ExecuteReader;
GridView1.DataBind();
}
}
Ok, we get this output:
Now, lets hide a column, based on say city. We say City = "Edmonton", we hide the control.
So, you use the itemData bound event.
I have in this sample both the bound fields (cells) collection hide example, and also for how do you do this with templated controls (find control).
So, the code is this:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
GridViewRow gvRow = e.Row;
// hide a Bound field
TableCell f = gvRow.Cells(4);
if (f.Text == "Edmonton")
f.Style("Display") = "none";
// hide a templated control
Label lbl = gvRow.FindControl("lblCity");
if (lbl.Text == "Edmonton")
lbl.Style("Display") = "none";
}
}
And now the output is this:

Related

Can't bind checkboxes in Gridview

I have a GridView that displays a list and the user can select a checkbox for each item.
So for example I check the second row. I can see in the database that the check value next to this description has updated to 1:
But when I go back into the GridView, all the checkboxes are blank again.
Code for GridView:
<asp:GridView style="width:75%"
ID="gvCVRTDetails"
ShowHeaderWhenEmpty="true"
CssClass="tblResults"
runat="server"
OnRowDataBound="gvCVRTDetails_RowDataBound"
DataKeyField="ID"
AutoGenerateColumns="false"
allowpaging="false"
AlternatingRowStyle-BackColor="#EEEEEE">
<HeaderStyle CssClass="tblResultsHeader" />
<Columns>
<asp:BoundField DataField="ChecklistID" HeaderText="ID" ></asp:BoundField>
<asp:BoundField DataField="Description" HeaderText="Checklist Items"></asp:BoundField>
<asp:TemplateField HeaderText ="Checked?" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:CheckBox ID="chkChecked" runat="server" ></asp:CheckBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Code behind:
protected void gvCVRTDetails_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
lookupCVRT work = (lookupCVRT)e.Row.DataItem;
GridView gv = sender as GridView;
e.Row.Attributes.Add("ID", "gvCVRTDetails_" + work.ID);
e.Row.Cells[0].Attributes.Add("onclick", "event.stopPropagation();");
CheckBox chkChecked = e.Row.FindControl("chkChecked") as CheckBox;
if(work.Checked)
{
chkChecked.Checked = true;
}
}
}
I tried setting chkChecked.Checked = true; if there is a value for the Checked field in the database but that didn't work. How do I get the checkboxes to show as ticked if the value in the database is equal to 1?
Binding the Grid:
protected void gridviewParent_SelectedIndexChanged(object sender, EventArgs e)
{
List<lookupCVRT> workDetails = lookupCVRT.GetChecklistItemsByChecklistID(Company.Current.CompanyID, ParentID.ToString(), gvCVRT.SelectedDataKey.Value.ToString());
gvCVRTDetails.DataSource = workDetails;
gvCVRTDetails.DataBind();
FireJavascriptCallback("setArgAndPostBack ();");
}
You should bind the checkbox to the property that you read from db, something like:
<asp:TemplateField HeaderText ="Checked?" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:CheckBox ID="chkChecked" Checked='<%# Bind("YourCheckPropertyFromModel") %>'runat="server" ></asp:CheckBox>
</ItemTemplate>
</asp:TemplateField>

Object reference not set to an instance of an object while passing data from gridview

I am passing values from a gridview to next page. The gridview is connected to a database.The gridview shows the data as I want but when I try to pass the row data of gridview to next page it throws an error 'Object reference not set to an instance of an object'.
The gridview is as follows:
<asp:GridView ID="GridView1" HeaderStyle-BackColor="#3AC0F2" HeaderStyle-ForeColor="White"
RowStyle-BackColor="#A1DCF2" AlternatingRowStyle-BackColor="White" AlternatingRowStyle-ForeColor="#000"
runat="server" AutoGenerateColumns="False" DataSourceID="SqlDataSource1" AllowPaging="True">
<AlternatingRowStyle BackColor="White" ForeColor="#000000"></AlternatingRowStyle>
<Columns>
<asp:BoundField DataField="TaskId" HeaderText="TaskId" ItemStyle-Width="30" InsertVisible="False" ReadOnly="True" SortExpression="TaskId" />
<asp:BoundField DataField="Title" HeaderText="Title" ItemStyle-Width="150" SortExpression="Title" />
<asp:BoundField DataField="Body" HeaderText="Body" SortExpression="Body" />
<asp:BoundField DataField="Reward" HeaderText="Reward" SortExpression="Reward" />
<asp:BoundField DataField="TimeAllotted" HeaderText="TimeAllotted" SortExpression="TimeAllotted" />
<asp:BoundField DataField="PosterName" HeaderText="PosterName" SortExpression="PosterName" />
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="lnkDetails" runat="server" Text="Send Details" PostBackUrl='<%# "~/test/Tasks.aspx?RowIndex=" + Container.DataItemIndex %>'></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<HeaderStyle BackColor="#3AC0F2" ForeColor="White"></HeaderStyle>
<RowStyle BackColor="#A1DCF2"></RowStyle>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:ABCD %>" SelectCommand="SELECT * FROM [Task]"></asp:SqlDataSource>
The code for 'Tasks.aspx.cs' is as below:
protected void Page_Load(object sender, EventArgs e)
{
if (this.Page.PreviousPage != null)
{
int rowIndex = int.Parse(Request.QueryString["RowIndex"]);
GridView GridView1 = (GridView)this.Page.PreviousPage.FindControl("GridView1");
GridViewRow row = GridView1.Rows[rowIndex];
lblTaskId.Text = row.Cells[0].Text;
lblTitle.Text = row.Cells[1].Text;
lblBody.Text = row.Cells[2].Text;
lblReward.Text = row.Cells[3].Text;
lblTimeAllotted.Text = row.Cells[4].Text;
lblPosterName.Text = row.Cells[5].Text;
}
}
I get an error message on the line below:
GridViewRow row = GridView1.Rows[rowIndex];
It would seem that FindControl method isn't actually finding the control, making your GridView1 variable null. Ensure the control is well inside the page and that the name is right.
EDIT:
If you are using master pages, there's indeed some issues with FindControl. Rick Strahls explains it in his blog:
*The problem is that when you use MasterPages the page hierarchy drastically changes.
Where a simple this.FindControl() used to give you a control instance you now have to
drill into the container hierarchy pretty deeply just to get to the content container.*
He also has an example on how to make it work. Basically, you must find your content control from the master page (using page.Master.FindControl). Then from that point you should be able to reach to your grid control.
In your scenario, since you want a control from the previous page:
var GridView1 = page.PreviousPage.Master.FindControl("ContentContainer").FindControl("GridView1") as GridView;
It looks to me like your gridview does not have any bound data when "this.Page.PreviousPage != null" is true. That is, unless you bind your data in some other initialization handler.
Because there is no data, there are no Rows which means that GridView1.Rows[rowIndex] would be null.

Reference specific checkbox in gridview

I have a GridView which show data retrived from database. I've made TemplateField (CheckBox) to GridView with this code:
<asp:GridView ID="dbRecordsContent" runat="server" AutoGenerateColumns="False" DataSourceID="SqlDataSource1" OnSelectedIndexChanged="dbRecordsContent_SelectedIndexChanged">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="myCheckBox" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="title" HeaderText="title" SortExpression="title" />
<asp:BoundField DataField="url" HeaderText="url" SortExpression="url" />
<asp:BoundField DataField="category" HeaderText="category" SortExpression="category" />
<asp:BoundField DataField="isChecked" HeaderText="isChecked" SortExpression="isChecked" />
</Columns>
</asp:GridView>
My grid view looks like this:
My question is: How do I know which checkbox ID is checked? For example:
I want to delete 2nd row when I press "Delete" button. Of course I will check second Checkbox, but how do I know which record to delete? How to reference second checkbox in a code?
In your delete button's click event handler you need to loop through all the rows in the grid and if a check box is checked, then you need to perform your delete logic, like this:
protected void DeleteButton_Click(object sender, EventArgs e)
{
foreach(GridViewRow row in dbRecordsContent.Rows)
{
// Only look for check boxes in data rows, ignoring header
// and footer rows
if (row.RowType == DataControlRowType.DataRow)
{
if (((CheckBox)row.FindControl("myCheckBox")).Checked)
{
// Do delete logic here
}
}
}
}
UPDATE:
To get the row number use the GridViewRow.RowIndex property, like this:
int rowNumber = row.RowIndex;
Read GridViewRow.RowIndex Property for more information.
try this,
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="myCheckBox" runat="server" AutoPostBack="true"
oncheckedchanged="CheckBox1_CheckedChanged" />
</ItemTemplate>
</asp:TemplateField>
code side,
protected void CheckBox1_CheckedChanged(object sender, EventArgs e)
{
GridViewRow row = ((GridViewRow)((CheckBox)sender).NamingContainer);
int index = row.RowIndex;
CheckBox cb1 = (CheckBox)Gridview.Rows[index].FindControl("myCheckBox");
string checkboxstatus;
if (cb1.Checked)
{
//write your code
}
else
{
//write your code
}
}

Nested GridView Problems

I am trying to nest one gridview within another, but I cannot get the data to populate in the second grid view. I am getting an error when trying to set the data source of the second data grid (saying it is null). Can anyone help?
Here is the aspx page:
<div id="divSource" runat="server" align="center">
<asp:GridView ID="Source" runat="server" AutoGenerateColumns="False" DataKeyNames="sourceLineItem" CSSClass="viewSourceGrid" OnRowDataBound="PopulateDateCodes">
<Columns>
<asp:TemplateField InsertVisible="False" HeaderStyle-Width="70px">
<ItemTemplate>
<asp:Label CssClass="sourceHeader" runat="server" Text= '<%# "Source: " + (Container.DataItemIndex + 1).ToString() %>'> </asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="nfdBroker" HeaderText="NFD/Broker" InsertVisible="False" ReadOnly="True" SortExpression="nfdBroker" />
<asp:BoundField DataField="locationDescription" HeaderText="Material Location" SortExpression="materialLocation" />
<asp:BoundField DataField="origPkg" HeaderText="Original Packaging?" SortExpression="origPkg" />
<asp:BoundField DataField="oemCC" HeaderText="OEM C of C? " InsertVisible="False" ReadOnly="True" SortExpression="oemCC" />
<asp:BoundField DataField="minBuyQty" HeaderText="Minimum Buy Qty" SortExpression="minBuyQty" />
<asp:BoundField DataField="deliveryInfo" HeaderText="Delivery" SortExpression="delUOM" />
<asp:TemplateField InsertVisible="False" HeaderText="Date Codes" >
<ItemTemplate>
<asp:GridView ID="DateCodeGrid" runat="server" InsertVisible="False" DataKeyNames="dateCode" CSSClass="viewSourceGrid" >
<Columns>
<asp:BoundField DataField="dateCode" SortExpression="dateCode">
<ItemStyle Width="20%" />
</asp:BoundField>
</Columns>
</asp:GridView>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
and then here is the code behind:
public partial class Controls_ViewSource : System.Web.UI.UserControl
{
//Set the Source Line Item
public int SourceLineItem { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
this.SourceLineItem = SourceLineItem;
RequestDB db = new RequestDB();
DataSet sources = db.GetSource(int.Parse(Request.QueryString["requestNumber"]), SourceLineItem);
Source.DataSource = sources;
Source.DataBind();
}
protected void PopulateDateCodes(object sender, GridViewRowEventArgs e)
{
RequestDB db = new RequestDB();
int index = e.Row.RowIndex;
GridView gv = (GridView)Source.Rows[0].FindControl("DateCodeGrid");
//int sourceLineItem = int.Parse(Source.DataKeyNames[0].ToString());
//Response.Write(Source.DataKeyNames[0].ToString());
DataSet dateCodes = db.GetDateCodes(71);
gv.DataSource = dateCodes;
gv.DataBind();
}
}
You would need to find the nested grid view in the row that is being data bound:
GridViewRow row = e.Row;
You need to make sure you are only doing this for data rows, not header or footer rows:
if(row.RowType == DataControlRowType.DataRow)
{
// Find the nested grid view
GridView nested = (GridView)row.FindControl("DateCodeGrid");
// The rest of your code for binding the nested grid view follows here
}

Passing Value when Select on GridView to another page

I have a GridView which is showing some data:
Entity_ID (PK)
Name
Description
Now I am enabling Select in my GridView. I need to pass Entity_ID to another page and in this page I am showing more contents for this Entity_ID.
How should I pick the Entity_ID value and pass it in as Query String? I have this code:
ProductsDataGridView.SelectedRows(0).Cells(1).Value.ToString()
Any responses will be appreciated! Thank you.
Add a new item template column in you grid and add the select link as below.
<asp:TemplateField HeaderText="View Details">
<ItemTemplate>
<asp:HyperLink ID="lnkSelect" runat='server' NavigateUrl='<%# String.Format("~/detailspagename.aspx?ID={0}", Eval("Entity_ID")) %>'>Select</asp:HyperLink>
</ItemTemplate>
This is what I did:
protected void gvAgentList_SelectedIndexChanged(object sender, EventArgs e)
{
GridViewRow row = gvAgentList.SelectedRow;
Response.Redirect("~/FrontEnd/Registration.aspx? EntityID=" + row.Cells[0].Text);
}
Use the OnRowSelected event. Once it calls that you can get the selected row and then the entity id. Next you can build a string with the entity id in the query string and response.redirect to that page.
You can also use DataKeys
set DataKeys='Entity_ID'
In the code behind you can access the same as selectedrow.DataKeys[rowindex]["Entity_ID"]
here selected row is the one you selected , rowindex the index and you get the corresponding Entity_ID
#GSGuy:
<asp:GridView runat ="server" ID = "gvAgentList"
AllowPaging = "True"
AutoGenerateSelectButton="True" AllowSorting="True" BackColor="#E8E8E8"
BorderColor="#003399" BorderStyle="Solid" BorderWidth="1px" Height="375px"
Width="823px" AutoGenerateColumns="False"
DataKeyNames="ID" DataSourceID="SqlDataSource1" onselectedindexchanged="gvAgentList_SelectedIndexChanged">
<AlternatingRowStyle ForeColor="#0066CC" />
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" InsertVisible="False"
ReadOnly="True" SortExpression="ID" />
<asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
<asp:BoundField DataField="Description" HeaderText="Description"
SortExpression="Description" />
<asp:TemplateField HeaderText="View Details">
<ItemTemplate>
<asp:HyperLink ID="lnkSelect" runat='server' NavigateUrl='<%# String.Format("~/detailspagename.aspx?ID={0}", Eval("Entity_ID")) %>'>Select</asp:HyperLink>
</ItemTemplate>
</Columns>
<HeaderStyle ForeColor="#3366FF" />
</asp:GridView>
protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
string fname, lname;
fname = GridView1.Rows[e.NewEditIndex].Cells[0].Text;
Session["fname"] = fname;
lname = GridView1.Rows[e.NewEditIndex].Cells[1].Text;
Session["lname"] = lname;
Response.Redirect("gridpass.aspx");
}
On gridpass.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
TextBox1.Text = Session["fname"].ToString();
TextBox2.Text = Session["lname"].ToString();
}
there are several approaches how to pass data between pages:
http://msdn.microsoft.com/en-us/library/6c3yckfw.aspx
the query string is ok if you don't mind the url will contain the ID
you can also consider Page.PreviousPage from the options above, which seems reasonable in your case

Categories