Check/Uncheck not working in the paging handled in gridview - c#

I have used the paging in the gridview.
I need the code for check/uncheck in gridview either in server side or client side.
I have tried without paging, it's working. I need it with paging.
<asp:TemplateField>
<HeaderTemplate>
<asp:CheckBox ID="chkHGrid" runat="server" />
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="chkGrid" runat="server" />
</ItemTemplate>
<ItemStyle HorizontalAlign="Center" />
<HeaderStyle HorizontalAlign="Center" />
</asp:TemplateField>

This technique is called maintaining the state of GridView CheckBox in Paging. One method to achieve this is as follows.
Create a Genric List of int or string to store the DataKeys related to Checked rows in it.
At PageIndexChanging before you set the PageIndex to new index. For each rows in GridView,
If checkbox is checked, store the id to the generic list.
If checkbox is unchecked & the ID exist in generic list, remove it from the list.
At RowDataBound event, for each DataRow, check if the DataKeyName is present in the Generic List. If so, find the CheckBox and make it checked.
A simple example with Products Table, Northwind Database is given below
The Markup
<asp:GridView ID="gvProducts" runat="server"
AllowPaging="True"
AutoGenerateColumns="False"
DataKeyNames="ProductID"
OnPageIndexChanging="gvProducts_PageIndexChanging"
OnRowDataBound="gvProducts_RowDataBound">
<Columns>
<asp:TemplateField HeaderText="Select">
<ItemTemplate>
<asp:CheckBox ID="chkSelect" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="ProductID" HeaderText="ProductID" InsertVisible="False"
ReadOnly="True" SortExpression="ProductID" />
<asp:BoundField DataField="ProductName" HeaderText="ProductName" SortExpression="ProductName" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="sdsProducts" runat="server"
ConnectionString='<%$ ConnectionStrings:NorthwindConnectionString %>'
SelectCommand="SELECT * FROM Products">
</asp:SqlDataSource>
The Code Behind
private List<int> ProductIDs
{
get
{
if (this.ViewState["ProductIDs"] == null)
{
this.ViewState["ProductIDs"] = new List<int>();
}
return this.ViewState["ProductIDs"] as List<int>;
}
}
protected void gvProducts_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
foreach (GridViewRow gvr in gvProducts.Rows)
{
CheckBox chkSelect = gvr.FindControl("chkSelect") as CheckBox;
if (chkSelect != null)
{
int productID = Convert.ToInt32(gvProducts.DataKeys[gvr.RowIndex]["ProductID"]);
if (chkSelect.Checked && !this.ProductIDs.Contains(productID))
{
this.ProductIDs.Add(productID);
}
else if (!chkSelect.Checked && this.ProductIDs.Contains(productID))
{
this.ProductIDs.Remove(productID);
}
}
}
}
protected void gvProducts_RowDataBound(object sender, GridViewRowEventArgs e)
{
GridViewRow gvr = e.Row;
if (gvr.RowType == DataControlRowType.DataRow)
{
CheckBox chkSelect = gvr.FindControl("chkSelect") as CheckBox;
if (chkSelect != null)
{
int productID = Convert.ToInt32(gvProducts.DataKeys[gvr.RowIndex]["ProductID"]);
chkSelect.Checked = this.ProductIDs.Contains(productID);
}
}
}

Related

Gridview ItemTemplate Checkbox to Check Based On Sql Numeric Feild

I Have a nested grid i want to check the column in grid when datakey is present in another table
Grid is like this
<asp:GridView Width="100%" DataKeyNames="PK_ServiceTypeID" HorizontalAlign="Center" runat="server" OnRowDataBound="gridServiceLocations_RowDataBound" AutoGenerateColumns="false" ID="gridServiceLocations" BackColor="White" BorderColor="#3366CC" BorderStyle="None" BorderWidth="1px" CellPadding="4">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<img alt="" style="cursor: pointer" src="../../Images/plus.png" />
<asp:Panel ID="pnlOrders" runat="server" Style="display: none">
<asp:GridView ID="gvOrders" runat="server" AutoGenerateColumns="false" Width="100%" DataKeyNames="PK_ServiceDetailID">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Service" HeaderText="Service" />
</Columns>
</asp:GridView>
</asp:Panel>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="ServiceTypeName" HeaderText="ServiceTypeName" HeaderStyle-HorizontalAlign="Center" />
</Columns>
</asp:GridView>
i have binded this grid from code behind
If I understand I think something like that will be working :
First, you'll need clear data to work with : get the value from your sql column and store it into a string ( or any type you want) array or List, something like that :
//Get your column value from your db
string myValueFromDb = "0000000062,0000000034,0000000016,0000000174,0000000055";
//Split the values into an list of string
myValues = new List<string>(myValueFromDb.Split(','));
//Here you have all your db values stored in the list myValues
But to access to your checkBox you must add an ID.
Like : asp:CheckBox runat="server" ID="checkBox" />
Now you'll need to check every row of your gridview. Something like that :
protected void gridServiceLocations_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow && e.Row.RowIndex != -1)
{
//Get the value of the current row DataKey
string dataKey = grid_view.DataKeys[e.Row.RowIndex].Value.ToString();
//GET THE ROW
GridViewRow row = e.Row;
//Now compare it with your value
if (myValues.Contains(dataKey))
{
//CHECK CASE
//The index of column of the column where the checkbox are (1 here, change it )
CheckBox checkbox = ((CheckBox)row.Cells[1].FindControl("checkBox"));
checkbox.Checked = true;
}
else
{
//UNCHECK CASE
CheckBox checkbox = ((CheckBox)row.Cells[1].FindControl("checkBox"));
checkbox.Checked = false;
}
}
}

Enable Linkbutton in Gridview when ASP.NET Button Clicked

I have a gridview that displays a record with some linkbuttons.
What I want is when my ASP.NET ButtonStart is clicked enable the LinkButton in the Gridview
<asp:GridView ID="gvData" runat="server" CellPadding="4" ForeColor="#333333"
GridLines="None" Width="688px" AllowPaging="True" AllowSorting="True"AutoGenerateColumns="False"
OnRowCommand="gvData_RowCommand"
OnRowDataBound="gvData_RowDataBound">
<AlternatingRowStyle BackColor="White" ForeColor="#284775" />
<Columns>
<asp:BoundField DataField="Id" HeaderText="ID" SortExpression="Id">
<ItemStyle HorizontalAlign="Center" />
</asp:BoundField>
<asp:BoundField DataField="Received" HeaderText="Received" SortExpression="Received"
ReadOnly="true">
<ItemStyle HorizontalAlign="Center" />
</asp:BoundField>
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:LinkButton ID="lbClose" runat="server" CausesValidation="False" CommandName="CloseClicked"
OnClick="CloseClick_Click">Close</asp:LinkButton>
</ItemTemplate>
<FooterStyle HorizontalAlign="Center" />
<ItemStyle HorizontalAlign="Center" />
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:button runat="server" text="Start" ID="btnStart" />
I know how to disable it in RowDataBound.
protected void gvData_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
LinkButton lbClose = (LinkButton)e.Row.Cells[5].FindControl("lbClose");
if (lbClose == null)
{
return;
}
var lblReceive = (Label)e.Row.FindControl("lblReceive ");
if (lblReceive .Text == "" && !IsPostBack)
{
lbClose.Enabled = true;
lbEdit.Enabled = true;
lbDelete.Enabled = true;
}
}
}
I believe you have to call RowDataBound from the BtnStart Click event but am not sure.
protected void btnStartTrans_Click(object sender, EventArgs e)
{
//Enable lblClose in gridview
}
Just loop through the rows in the grid view and enable the lbClose in each row, like this:
protected void btnStartTrans_Click(object sender, EventArgs e)
{
// Loop through all rows in the grid
foreach (GridViewRow row in grid.Rows)
{
// Only look for `lbClose` in data rows, ignore header and footer rows, etc.
if (row.RowType == DataControlRowType.DataRow)
{
// Find the `lbClose` LinkButton control in the row
LinkButton theLinkButton = (LinkButton)row.FindControl("lbClose");
// Make sure control is not null
if(theLinkButton != null)
{
// Enable the link button
theLinkButton.Enabled = true;
}
}
}
}

Issue with getting CheckBox value in GridView

I have a GridView that contains a CheckBox control. Once the users check the rows that they want, they click a button and I have to update the database for each checked row.
I have the code to iterate trough the gridview rows and look at the checkbox value, but its always false, even if its checked. I do get a reference to the checkbox in ignore but it is always false. What am I missing here?
aspx.cs file:
protected void Ignore_Click(object sender, EventArgs e)
{
foreach (GridViewRow row in grdNotReceived.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
CheckBox ignore = (CheckBox)row.FindControl("chkIgnore");
if (ignore.Checked)
{
// Update Database
}
}
}
}
.aspx page:
<asp:GridView ID="grdNotReceived" runat="server"
Width="600px"
CssClass="mGrid"
AlternatingRowStyle-CssClass="alt"
PagerStyle-CssClass="pgr" AutoGenerateColumns="false">
<AlternatingRowStyle CssClass="alt"/>
<Columns>
<asp:BoundField DataField="Store" HeaderText="Store" />
<asp:BoundField DataField="Dept" HeaderText="Dept" />
<asp:BoundField DataField="Type" HeaderText="Type" />
<asp:BoundField DataField="RefNumber" HeaderText="RefNumber" />
<asp:BoundField DataField="Date" HeaderText="Date" />
<asp:BoundField DataField="Vendor" HeaderText="Vendor" />
<asp:BoundField DataField="Total" HeaderText="Total" />
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="chkIgnore" runat="server" Checked="false" />
</ItemTemplate>
<EditItemTemplate>
<asp:CheckBox ID="chkIgnore" runat="server" Checked="false" />
</EditItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
GridView databind method:
protected void LoadExceptions()
{
Database db = new Database();
SqlCommand sql = new SqlCommand();
sql.CommandText = "getSobeysNotReceived";
this.grdNotReceived.DataSource = db.GetSprocDR(sql);
this.grdNotReceived.DataBind();
db.Close();
}
If your databinding function ( LoadExceptions() ) is being called somwhere on the page load (like the Load event or class constructor) then it's overriding the changes the user has made in the form.
Don't databind if the page is in post back, you can add an if (!Page.IsPostBack) before calling LoadExceptions() or you can update LoadExceptions() to check it:
protected void LoadExceptions()
{
if (!Page.IsPostBack)
{
Database db = new Database();
SqlCommand sql = new SqlCommand();
sql.CommandText = "getSobeysNotReceived";
this.grdNotReceived.DataSource = db.GetSprocDR(sql);
this.grdNotReceived.DataBind();
db.Close();
}
}

GridView does not update values on postback?

I have a gridview with some custom templates:
<asp:GridView ID="gvGroups" runat="server" AutoGenerateColumns="False"
CssClass="table table-hover table-striped" GridLines="None" >
<Columns>
<asp:BoundField DataField="GroupDescription" HeaderText="Name" ReadOnly="True"
SortExpression="GroupDescription" />
<asp:TemplateField HeaderText="Administrator">
<ItemTemplate>
<asp:CheckBox ID="cbAdmin" runat="server"
Checked='<%# Boolean.Parse((Boolean)Eval("IsReadOnly") ? "True" : "False") ? false : true %>'/>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Remove">
<ItemTemplate>
<asp:CheckBox ID="cbRemove" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="ID" SortExpression="GroupID" Visible="False">
<ItemTemplate>
<asp:Label ID="lblID" runat="server" Text='<%# Bind("GroupID") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
I then have a button that I click and that is supposed to change group administration and remove groups that are checked.
Here is the button code:
protected void btnSave_Click(object sender, EventArgs e)
{
foreach (GridViewRow gvr in gvGroups.Rows)
{
CheckBox cbAdmin = (CheckBox)gvr.FindControl("cbAdmin");
CheckBox cbRemove = (CheckBox)gvr.FindControl("cbRemove");
Label lblID = (Label)gvr.FindControl("lblID");
int id;
bool idValid = int.TryParse(lblID.Text,out id);
bool isReadOnly = !cbAdmin.Checked;
if (idValid)
{
Group g = SecurityManager.GetGroup(id);
if (g.IsReadOnly != isReadOnly)
{
bool updateSuccess = SecurityManager.ChangeGroupPermissions(id, isReadOnly);
}
if (cbRemove.Checked)
{
bool removeEmpSuccess = SecurityManager.RemoveEmployeesFromGroup(id);
bool removeSuccess = SecurityManager.RemoveGroup(id);
}
}
}
}
I used the debugger and even when I uncheck admin on all groups, when I look at cbAdmin.Checked, it is still true, which is the same value it started with, thus nothing ever happens.
What could be the problem? Why am I not seeing the updated values on the button postback?
Thanks
You have to call GridView#DataBind() within if(!IsPostBack){ }
Also you need to set AutoPostBack property of the textboxes to "true"
I guess that you're databinding the GridView on postbacks. That will load the data from database again and prevent changes. So ue the PostBack property of the Page:
protected void Page_Load(Object sender, EventArgs e)
{
if(!IsPostBack)
{
DataBindGridView();
}
}

Accessing GridView data from a templatefield

<asp:GridView ID="gvGrid" runat="server" AutoGenerateColumns="False"
DataSourceID="dsDataSource" AllowPaging="True" PageSize="20" >
<Columns>
<asp:BoundField DataField="Field1" HeaderText="Field1"
SortExpression="Field1" />
<asp:BoundField DataField="Field2" HeaderText="Field2"
SortExpression="Field2" />
<asp:TemplateField HeaderText="TemplateField1">
<ItemTemplate>
<asp:Label id="lblComments" runat="server" Text=" i use a function to compute"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField ShowSelectButton="True" SelectText="Complete" HeaderText ="Status" />
<asp:TemplateField HeaderText="Action">
<ItemTemplate>
<asp:Button ID="btnComplete" runat="server" Text="Complete" onclick="btnComplete_Click"/>
<asp:Button ID="btnAddComment" runat="server" Text="Add Comment" onclick="btnAddComment_Click" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
protected void btnComplete_Click(object sender, EventArgs e)
{
String Field1 = gvGrid.SelectedRow.Cells[1].Text; // throws an error at runtime
//I want to be able to access the row data do some computation and then be able to insert it into the database
// Reason why I am trying to use it as a template field instead of a commandfield is because I want to make it not visible when it meets certain condition.
}
Also, it would be great if you could let me know a better way to do it, maybe using the command field and if there is a way to toggle its visibility. I don't mind using LinkButton either.
You can do it like this:
protected void btnComplete_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
GridViewRow gvRow = (GridViewRow)btn.Parent.Parent;
//Alternatively you could use NamingContainer
//GridViewRow gvRow = (GridViewRow)btn.NamingContainer;
Label lblComments = (Label)gvRow.FindControl("lblComments");
// lblComments.Text ...whatever you wanted to do
}
here is how you can access to the gridview row:
protected void btnComplete_Click(object sender, EventArgs e)
{
foreach (GridViewRow row in gvGrid.Rows)
{
Label lblComments = row.FindControl("lblComments") as Label;
....//you can do rest of the templatefiled....
}
}

Categories

Resources