Checkbox on Datagrid for ASP - asp.net

I have a data grid on my project with a Checkbox as a TemplateField; but I can't acces the checkbox.checked property. Does anyone have any idea?
My ASP code:
<asp:GridView ID="GVP" runat="server" AutoGenerateColumns="False" DataSourceID="DSP">
<Columns>
<asp:TemplateField HeaderStyle-Width="5%" ItemStyle-Width="5%" FooterStyle-Width ="5%">
<ItemTemplate>
<asp:CheckBox ID="SelectCb" runat="server"></asp:CheckBox>
</ItemTemplate>
<FooterStyle Width="5%"/>
<HeaderStyle Width="5%"/>
<ItemStyle Width="5%"/>
</asp:TemplateField>
<asp:BoundField DataField="Answers" HeaderText="Options" SortExpression="Answers" />
</Columns>
</asp:GridView>
My VB code behind:
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles buttonNext.Click
Dim SelectedBox As Boolean = False
For Each row As GridViewRow In GVP.Rows
Dim cb As CheckBox = row.FindControl("SelectCb")
If cb IsNot Nothing AndAlso cb.Checked Then
SelectedBox = True
Dim RID As Integer = Convert.ToInt32(GVP.DataKeys(row.RowIndex).Value)
Else
ShowMessage("You did not select anything")
End if

try this:
For Each row As GridViewRow In gvTest.Rows
Dim cb As CheckBox = row.FindControl("SelectCb")
If (CType(row.FindControl("SelectCb"), CheckBox)).Checked = True Then
SelectedBox = True
Dim RID As Integer = Convert.ToInt32(gvTest.DataKeys(row.RowIndex).Value)
End If
Next

It's hard to tell what you are trying to do here and how you are testing but my guess is that this is because you are not checking for row type. So the first row is actually the header and therefore will not have a checkbox at all (and you will get the message).
For Each row As GridViewRow In GVP.Rows
If row.RowType = DataControlRowType.DataRow Then
Dim cb As CheckBox ...

The problem really resided on the Page_Load where I was binding the grid to the datasource; I deleted it and the problem was solved.

Related

Persisting Checkbox State when Paging Gridview

In a nutshell, I am trying to maintain the CheckBox state on a GridView while paging. I am successfully tracking the CheckBox states in the ViewState (using an ArrayList on the row IDs) and I can successfully perform an action on all the checked rows on multiple pages.
However, once I go to a new page and then page back, the checked CheckBoxes are no longer checked (though the row ID still exists in the ArrayList in the ViewState). I have to assume this has something to do with the page life cycle.
I have read the entire ASP.NET Page Life Cycle Overview and tried binding the GridView in the PreRender event (and not binding the GridView at all) which didn't work either. All the examples I found online were loading the GridView DataSource from code behind using a DataTable filled from a SQLDataAdapter. I am using a DataSourceID (from a SQLDataSource) assigned directly to the GridView.
I still can't seem to determine why this is failing. Thanks in advance for your time.
ASPX Page
<asp:SqlDataSource ID="sdsAdminIntakes" runat="server" CancelSelectOnNullParameter="false"
Connectionstring="<%$ ConnectionStrings:MyAppSiteDB %>"
ProviderName="<%$ ConnectionStrings:MyAppSiteDB.ProviderName %>"
SelectCommand="admin_intakes_search"
SelectCommandType="StoredProcedure">
<SelectParameters>
<asp:Parameter Name="specialist_id" />
<asp:Parameter Name="caller_name" />
<asp:Parameter Name="case_number" />
<asp:Parameter Name="case_status" />
</SelectParameters>
</asp:SqlDataSource>
<asp:GridView ID="grdAdminIntakes" runat="server"
DataKeyNames="intake_id" DataSourceID="sdsAdminIntakes"
AutoGenerateColumns="False" AllowSorting="True"
AllowPaging="True" PageSize="20">
<Columns>
<asp:TemplateField>
<HeaderTemplate>
<asp:CheckBox runat="server" ID="chkAll" />
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox runat="server" ID="chkIntake" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="specialist_full_name" HeaderText="Current Specialist"
SortExpression="specialist_full_name" >
</asp:BoundField>
<asp:BoundField DataField="caller_name" HeaderText="Caller"
SortExpression="caller_name" >
</asp:BoundField>
<asp:BoundField DataField="case_number" HeaderText="Case #"
SortExpression="case_number" >
</asp:BoundField>
<asp:BoundField DataField="cmp_status" HeaderText="Case Status"
SortExpression="case_status" ItemStyle-CssClass="case_status" >
</asp:BoundField>
</Columns>
</asp:GridView>
ASPX.VB Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
grdAdminIntakes.DataBind()
End If
End Sub
Private Sub grdAdminIntakes_PageIndexChanging(sender As Object, e As System.Web.UI.WebControls.GridViewPageEventArgs) Handles grdAdminIntakes.PageIndexChanging
GetCheckboxState()
grdAdminIntakes.PageIndex = e.NewPageIndex
grdAdminIntakes.DataBind()
SetCheckboxState()
End Sub
Private Sub GetCheckboxState()
Dim lstArray As ArrayList
If ViewState("SelectedRecords") IsNot Nothing Then
lstArray = DirectCast(ViewState("SelectedRecords"), ArrayList)
Else
lstArray = New ArrayList()
End If
Dim chkAll As CheckBox = DirectCast(grdAdminIntakes.HeaderRow.Cells(0).FindControl("chkAll"), CheckBox)
For i As Integer = 0 To grdAdminIntakes.Rows.Count - 1
If chkAll.Checked Then
If Not lstArray.Contains(grdAdminIntakes.DataKeys(i).Value) Then
lstArray.Add(grdAdminIntakes.DataKeys(i).Value)
End If
Else
Dim chk As CheckBox = DirectCast(grdAdminIntakes.Rows(i).Cells(0).FindControl("chkIntake"), CheckBox)
If chk.Checked Then
If Not lstArray.Contains(grdAdminIntakes.DataKeys(i).Value) Then
lstArray.Add(grdAdminIntakes.DataKeys(i).Value)
End If
Else
If lstArray.Contains(grdAdminIntakes.DataKeys(i).Value) Then
lstArray.Remove(grdAdminIntakes.DataKeys(i).Value)
End If
End If
End If
Next
ViewState("SelectedRecords") = lstArray
End Sub
Private Sub SetCheckboxState()
Dim currentCount As Integer = 0
Dim chkAll As CheckBox = DirectCast(grdAdminIntakes.HeaderRow.Cells(0).FindControl("chkAll"), CheckBox)
chkAll.Checked = True
Dim lstArray As ArrayList = DirectCast(ViewState("SelectedRecords"), ArrayList)
For i As Integer = 0 To grdAdminIntakes.Rows.Count - 1
Dim chk As CheckBox = DirectCast(grdAdminIntakes.Rows(i).Cells(0).FindControl("chkIntake"), CheckBox)
If chk IsNot Nothing Then
chk.Checked = lstArray.Contains(grdAdminIntakes.DataKeys(i).Value)
If Not chk.Checked Then
chkAll.Checked = False
Else
currentCount += 1
End If
End If
Next
End Sub
After several more hours of research, I was finally able to get this working by moving the SetCheckboxState() out of the grdAdminIntakes_PageIndexChanging event and into the grdAdminIntakes_DataBound event.

copy row from asp.net gridview to new page using VB

I am trying to copy a row from a gridview to be displayed on a new page through a button in one of the columns in the gridview. I have my gridview populated from an Access database that is linked to my project. I have tried several different things, but nothing will display the row information when the project is ran. The current code I am trying from the actual dataview is:
Example 1a
<asp:GridView ID="Grid1" runat="server" Width ="90%" AutoGenerateColumns="false" OnRowDeleting="Grid1_RowDeleting" DataKeyNames="Title">
<Columns>
<asp:BoundField DataField="Title" HeaderText="Title" />
<asp:BoundField DataField="Console" HeaderText="Console" />
<asp:BoundField DataField="Year_Released" HeaderText="Year Released" />
<asp:BoundField DataField="ESRB" HeaderText="ESRB Rating" />
<asp:BoundField DataField="Score" HeaderText="Personal Score" />
<asp:BoundField DataField="Publisher" HeaderText="Publisher" />
<asp:BoundField DataField="Developer" HeaderText="Developer" />
<asp:BoundField DataField="Genre" HeaderText="Genre" />
<asp:BoundField DataField="Purchase" HeaderText="Purchase Date" />
<asp:TemplateField ItemStyle-Width="7%" ShowHeader="False">
<ItemTemplate>
<asp:LinkButton ID="lnkDetails" runat="server" Text="View" PostBackUrl='<%# "~/ViewDetails.aspx?RowIndex=" & Container.DataItemIndex %>'/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
And the codebehind code on the page where I am trying to have the code be displayed is:
Example 1b
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
If Me.Page.PreviousPage IsNot Nothing Then
Dim rowIndex As Integer = Integer.Parse(Request.QueryString("RowIndex"))
Dim GridView1 As GridView = DirectCast(Me.Page.PreviousPage.FindControl("Grid1"), GridView)
Dim row As GridViewRow = GridView1.Rows(rowIndex)
lblTitle.Text = row.Cells(0).Text
lblConsole.Text = row.Cells(1).Text
lblYear.Text = row.Cells(2).Text
lblESRB.Text = row.Cells(3).Text
lblScore.Text = row.Cells(4).Text
lblPublisher.Text = row.Cells(5).Text
lblDeveloper.Text = row.Cells(6).Text
lblGenre.Text = row.Cells(7).Text
lblPurchase.Text = row.Cells(8).Text
End If
End Sub
I have also tried another set of code where the button on the gridview was:
Example 2a
<asp:Button ID="btnLink" runat="server" Text="View Details" PostBackUrl='<%# Eval("Title", "~/ViewDetails.aspx?Id={0}") %>'/>
Where the codebehind code is:
Example 2b
Protected Sub Page_Load(sender As Object, e As EventArgs)
If Not IsPostBack Then
Dim GameTitle As String = Request.QueryString("Id")
Dim connString As String = "PROVIDER=Microsoft.ACE.OLEDB.12.0;" + "DATA SOURCE=" + Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "App_Data" + "db1.accdb")
Using connection As New OleDbConnection(connString)
connection.Open()
Dim reader As OleDbDataReader = Nothing
Dim command As New OleDbCommand((Convert.ToString("SELECT * from [Video_Games] WHERE Title='") & GameTitle) + "'", connection)
reader = command.ExecuteReader()
While reader.Read()
lblTitle.Text = reader(0).ToString()
lblConsole.Text = reader(1).ToString()
lblYear.Text = reader(2).ToString()
lblESRB.Text = reader(3).ToString()
lblScore.Text = reader(4).ToString()
lblPublisher.Text = reader(5).ToString()
lblDeveloper.Text = reader(6).ToString()
lblGenre.Text = reader(7).ToString()
lblPurchase.Text = Convert.ToDateTime(reader(8).ToString()).ToShortDateString()
End While
End Using
End If
End Sub
End Class
I have tried making variations of both, mainly the second, but whatever I try the labels are not populated with the row information. Any assistance would be appreciated, and I can post any other code needed, like how I populated the gridview. Thank you.
It was as simple as changing the AutoEventWireup to "true" in my .aspx file.

Change the visibility property from code behind

I'm trying to hide the 'Delete' link if value in CUST_ORDER_ID = 'X' but I don't know how to set the visibility property to "False"
My asp.
<Columns>
<asp:CommandField ShowDeleteButton="True" />
<asp:BoundField DataField="ROWID" SortExpression="ROWID" Visible="False"> </asp:BoundField>
<asp:BoundField DataField="CUST_ORDER_ID" HeaderText="ORDER ID" SortExpression="CUST_ORDER_ID">
<ItemStyle Width="50px"></ItemStyle>
and the code behind
Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
'check is row non order type and allow user to delete
Dim oid As TableCell = e.Row.Cells(2)
If oid.Text = "X" Then
Dim tb As Button = e.Row.Cells(1).Controls(1)
'Dim tb = e.Row.FindControl("DeleteButton")
tb.Visible = "False"
End If
End If
End Sub
Thanks for all of the ideas. This is the cleanest solution I found on this site but it was in c# so converted to vb.
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton runat="server" ID="DeleteButton" CommandName="Delete" Text="Delete" />
</ItemTemplate>
</asp:TemplateField>
and the code behind
Dim oid As TableCell = e.Row.Cells(2)
Dim tb = e.Row.FindControl("DeleteButton")
If oid.Text = "X" Then
tb.Visible = True
Else
tb.Visible = False
End If
Maybe you can change to Templatefield
<asp:TemplateField HeaderText="Col1">
<ItemTemplate>
<asp:label ID="lbl1" runat="server" text='<%#left(DataBinder.Eval(Container.DataItem, "field1"),20)%>'>
</asp:label>
</ItemTemplate>
With this code:
Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound
Dim lbl1 As Label
If e.Row.RowType = DataControlRowType.DataRow Then
lbl1 = CType(e.Row.FindControl("lbl1"), Label)
If oid.Text = "X" Then
lbl1 .Visible = "False"
End If
End If
End Sub
You can use almost any control in template.

Editing a row in a gridview by the use of the click into button event

I have this gridview in my application :
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" AllowPaging="True">
<Columns>
<asp:TemplateField >
<ItemTemplate>
<asp:Button ID="Savebtn" runat="server" Text="تحديث البيانات" OnClick="gv_RowEditing"/>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="السعر الأقصى">
<ItemTemplate>
<asp:TextBox ID="mintxt" runat="server" Text='<%#Eval("prix max")%>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="السعر الأدنى" >
<ItemTemplate>
<asp:TextBox ID="maxtxt" runat="server" Text='<%#Eval("prix min")%>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Datvente" HeaderText="التاريخ" SortExpression="Datvente" />
<asp:BoundField DataField="NomAdh" HeaderText="الإسم و اللقب" SortExpression="NomAdh" />
<asp:BoundField DataField="CodAdh" HeaderText="المنخرط" SortExpression="CodAdh" />
<asp:TemplateField >
<ItemTemplate>
<asp:HiddenField ID="Ref" runat="server" Value='<%#Eval("Ref")%>'/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
The event of the click into button :
Protected Sub gv_RowEditing(ByVal sender As Object, ByVal e As EventArgs)
Try
Dim min As Double = Double.Parse(GridView1.SelectedRow.Cells("mintxt").ToString())
Dim max As Double = Double.Parse(GridView1.SelectedRow.Cells("maxtxt").ToString())
Dim reference As String = Double.Parse(GridView1.SelectedRow.Cells("Ref").ToString())
If min > max Then
avis2.Text = "الصيغة خاطئة"
Return
End If
DataAccessLayer.updatetraitementprix(min, max, reference)
avis2.Text = ""
FillingGrid(Session("region"), Session("date"), Session("speculation"))
Catch ex As Exception
avis2.Text = "الصيغة خاطئة"
GridView1.Visible = True
Return
End Try
Me.FillingGrid(Session("region"), Session("date"), Session("speculation"))
End Sub
I need to get the value of the column Ref and the new values of fields maxtxt and mintxt . but it didn't work
What are the reasons of this problem?
How can i resolve it?
There is absolutely need of RowEditing event. What you are doing is firing a simple OnClick event. So make these changes.
Markup ( Name change so that you may not confuse it with RowEditing event )
<asp:TemplateField >
<ItemTemplate>
<asp:Button ID="Savebtn" runat="server"
Text="تحديث البيانات"
OnClick="Savebtn_Click" />
</ItemTemplate>
</asp:TemplateField>
Code-behind
Protected Sub Savebtn_Click(sender As Object, e As System.EventArgs)
Dim btn As Button = CType(sender, Button)
Dim clickedRow As GridViewRow = CType(btn.NamingContainer, GridViewRow)
Dim minTextBox As TextBox = CType(clickedRow.FindControl("mintxt"), TextBox)
Dim maxTextBox As TextBox = CType(clickedRow.FindControl("maxtxt"), TextBox)
Dim refHidden As HiddenField = CType(clickedRow.FindControl("Ref"), HiddenField)
Dim min As Double = Double.Parse(minTextBox.Text)
Dim max As Double = Double.Parse(maxTextBox.Text)
Dim reference As Double = Double.Parse(refHidden.Value)
'rest of the code goes here
End Sub
Since the TextBox controls are inside of TemplateField's, you have to use Control#FindControl method to find them. Be aware of the Cell's index for each control.
Dim tbMin As TextBox = CType(GridView1.SelectedRow.Cells(1).FindControl("mintxt"), TextBox)
Dim min As Double = Double.Parse(tbMin.Text)
The reason you're getting this error is actually because the selectedrow is nothing, so you first need to get the current selected row then access all the controls in that row.
Please replace your code to the following:
Protected Sub gv_RowEditing(ByVal sender As Object, ByVal e As EventArgs)
Try
'First, get the saveBtn
Dim saveBtn As Button = DirectCast(sender, Button)
'Next, get the selected row of that button
Dim selectedRow As GridViewRow = DirectCast(saveBtn.Parent.Parent, GridViewRow)
'Now you can access all the controls of that row
Dim mintxt As TextBox = DirectCast(selectedRow.FindControl("mintxt"), TextBox)
Dim maxtxt As TextBox = DirectCast(selectedRow.FindControl("mintxt"), TextBox)
Dim Ref As HiddenField = DirectCast(selectedRow.FindControl("Ref"), HiddenField)
'Get the values of the controls
Dim min As Double = Double.Parse(mintxt.Text)
Dim max As Double = Double.Parse(maxtxt.Text)
Dim refVal As Double = Double.Parse(Ref.Value)
If min > max Then
avis2.Text = "الصيغة خاطئة"
Return
End If
DataAccessLayer.updatetraitementprix(min, max, refVal)
avis2.Text = ""
FillingGrid(Session("region"), Session("date"), Session("speculation"))
Catch ex As Exception
avis2.Text = "الصيغة خاطئة"
GridView1.Visible = True
Return
End Try
Me.FillingGrid(Session("region"), Session("date"), Session("speculation"))
End Sub

Checkbox update in GridView

When people search on my website using a GridView I would like to have a checkbox column that they click on which will change the value in a column called STATUS to U. I'm having a heck of a time finding code that works so I was hoping you guys could help. I'm a COMPLETE NOOB so please be descriptive if you know the answer.
Code for Checkbox button - Currently when I search it comes back saying that it cannot convert string to boolean.
<asp:TemplateField HeaderText="Successful Contact?">
<EditItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" checked='<%#Bind("status")%>' AutoPostBack="true" />
</EditItemTemplate>
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" checked='<%#Bind("status")%>'
Enabled="False" /></ItemTemplate>
</asp:TemplateField>
This is the vb code
Protected Sub GridView1_RowUpdating(ByVal sender As Object, ByVal e As GridViewUpdateEventArgs)
For Each GridViewRow In GridView1.Rows
Dim row As GridViewRow = GridView1.Rows(e.RowIndex)
Dim value As Boolean
value = DirectCast(GridView1.Rows(e.RowIndex).Cells(0).FindControl("CheckBox1"), CheckBox).Checked
Dim connectionString As String = ConfigurationManager.ConnectionStrings("Data Source=server;Initial Catalog=i3FCC01;Integrated Security=True;").ConnectionString
Dim com_sql As New SqlClient.SqlCommand
Dim insertSql As String
insertSql = "Update CallQueueFCC Set Status='U' where Id = #id"
Using myConnection As New SqlConnection(connectionString)
myConnection.Open()
Dim myCommand As New SqlCommand(insertSql, myConnection)
myCommand.Parameters.AddWithValue("#status", value)
myCommand.ExecuteNonQuery()
myConnection.Close()
End Using
Next
GridView1.EditIndex = -1
DataBind()
End Sub
You are binding Status value for check box checked attribute which takes Boolean value.
But status has string value as you are binding string to Boolean it is throwing error.
Like Kiran mentioned earlier, status has a string value so you need to do some firefighting in the row databound event.
Markup
<asp:TemplateField HeaderText="Successful Contact?">
<EditItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" AutoPostBack="true" />
</EditItemTemplate>
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server"
Enabled="False" /></ItemTemplate>
</asp:TemplateField>
Code behind
Protected Sub GridView1_RowDataBound(sender As Object, e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
'Evaluate the state of the check box, true when status =U , and false otherwise
Dim itemstatus As Boolean=If(DataBinder.Eval(e.Row.DataItem, "Status"), True, False)
Dim CheckBoxItemTemp As CheckBox=CType(e.Row.FindControl("CheckBox1"), CheckBox)
CheckBoxItemTemp.Checked=itemstatus
End if
If e.Row.RowState & DataControlRowState.Edit Then
'same as above but now for edit item template
Dim editstatus As Boolean=If(DataBinder.Eval(e.Row.DataItem, "Status"), True, False)
Dim CheckBoxEditTemp As CheckBox=CType(e.Row.FindControl("CheckBox1"), CheckBox)
CheckBoxEditTemp.Checked=editstatus
End if
End Sub

Resources