I need to create a table whose first column is an image button that deletes the whole row when clicked (actually it deletes a database row then reloads the HTML table).
The table and the buttons display as expected, but when I click a button, nothing happens.
To make each button clickable, I used AddHandler.
deletion is the sub that handles the clicks, it will get the button's ID (which contains the database table id for the row the user wants to delete) then calls a stored procedure with the ID as parameter and finally reloads the HTML table. I didn't implement it yet but the debugger can't reach it.
The VB code is as follows
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
If Request.Cookies("myuser") Is Nothing OrElse Request.Cookies("myuser")("isconnected") <> "1" Then
Response.Redirect("/Default.aspx")
Else
N_User = CInt(Request.Cookies("myuser")("N_User"))
Dim dbc As DBConnection
dbc = New DBConnection("192.168.1.45", "CorpDB", "someuser", "xxxxxxx")
Dim dt As DataTable
Try
dt = dbc.getQueryData("select lastname, isnull(firstname,'') from itc where N_User=" & CStr(N_User))
If dt.Rows.Count > 0 Then
End If
Catch ex As Exception
' do nothing for now
End Try
End If
FillTable()
End Sub
Protected Sub deletion(sender As Object, e As ImageClickEventArgs)
' confirm deletion
' Run a stored procedure to delete the comment row
FillTable()
End Sub
Private Sub FillTable()
Dim dbc As DBConnection
Dim dt As DataTable
Dim tr As TableRow
Dim tc As TableCell
Dim ibutton As ImageButton
Dim sqlquery As String
If PickProject.SelectedValue = "" Then
Exit Sub
End If
sqlquery = "select N_follow, Name=isnull(isnull(lastname + ' ','') + Nom, 'Anon'), Date=convert(varchar,DFollow,103), Stage=isnull(FreeField1,''), [Text]=isnull(dbo.RTFtoText(txt),'') from AF_FOLLOW a left outer join USERS u on u.N_User = a.N_User_Create where Numero=" & PickProject.SelectedValue & "order by DFollow desc"
dbc = New DBConnection("192.168.1.45", "CorpDB", "someuser", "xxxxxxx")
Try
dt = dbc.getQueryData(sqlquery)
Catch ex As Exception
' Show something,
Exit Sub
End Try
If dt.Rows.Count > 0 Then
CommentTable.Rows.Clear()
For Each row As DataRow In dt.Rows
' Create a new row
tr = New TableRow
' column #1 : delete button
tc = New TableCell
tc.CssClass = "SelectDel"
ibutton = New ImageButton()
ibutton.ID = "ibutton_" & row.Item("N_follow")
ibutton.ImageUrl = "img/remove_icon.png"
AddHandler ibutton.Click, AddressOf deletion
tc.Controls.Add(ibutton)
tr.Cells.Add(tc)
' Column #2 : Date
tc = New TableCell
tc.Text = row.Item("Date")
tr.Cells.Add(tc)
' Column #3 : Stage
tc = New TableCell
tc.Text = row.Item("Stage")
tr.Cells.Add(tc)
' Column #4 : name
tc = New TableCell
tc.Text = row.Item("Name")
tr.Cells.Add(tc)
' Column #5 : Comment
tc = New TableCell
tc.Text = row.Item("Text")
tr.Cells.Add(tc)
' Add the created row to the table
CommentTable.Rows.Add(tr)
Next
CommentTable.Visible = True
Else
End If
End Sub
For some reason, it's Page_Load that gets triggered when I click a button. But I got the same behavior with a DropDownList, first Page_Load gets fired up, then PickProject_SelectedIndexChanged and the event handler works as intended.
I googled and searched StackOverflow a lot , but none of the solutions suggested seems to work.
What did I miss ?
Related
UPDATE
from this i bind gridview
Public Function uplif() As DataTable
Dim dt As New DataTable()
gridvieew1.Visible = True
Try
dt.Columns.AddRange(New DataColumn(1) {New DataColumn("ID", GetType(Integer)),
New DataColumn("Name", GetType(String))}
Dim Content As String = Request.Form(textbox1.UniqueID)
For Each row As String In Content .Split(ControlChars.Lf)
If Not String.IsNullOrEmpty(row) Then
dt.Rows.Add()
Dim i As Integer = 0
For Each cell As String In row.Split(ControlChars.Tab)
If i > 1 Then
labelmessage.Text = "More than 2 columns not Allowed !!"
textbox1.Text = ""
Else
If cell.Trim() = "" Then
cell = "0"
End If
dt.Rows(dt.Rows.Count - 1)(i) = cell
i += 1
End If
Next
End If
Next
gridvieew1.DataSource = dt
gridvieew1.DataBind()
Catch Ex As Exception
labelmessage.CssClass = "alertNo"
labelmessage.Text = Ex.Message
End Try
Return dt
End Function
Protected Sub PasteToGridView(sender As Object, e As EventArgs)
uplif()
End Sub
now when i try to add new row like this
Private Sub AddNewRowToGrid()
Dim dt As DataTable = uplif()
Dim NewRow As DataRow = dt.NewRow()
dt.Rows.Add(NewRow)
gridvieew1.DataSource = dt
gridvieew1.DataBind()
End Sub
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
AddNewRowToGrid()
End Sub
this shows same output like add new row and replace previous data which is already in gridview and also this shows an error
Object reference not set to an instance of an object.
after click on add new row
ID Name
where as i want like this
ID Name
1 abc
2 def
(here new empty row when click on button )
As was pointed out in a comment to your post, the problem is in these two lines:
Dim dt As New DataTable()
...
gridview1.DataSource = dt
That creates a brand new DataTable and binds the grid view to it. You don't copy data over, and you don't alter the existing gridview's table.
The correct fix here would be to get the DataTable from the gridview's DataSource and make any changes you need to to that. Don't create a new DataTable.
Get the already assigned DataSource and then add the Row. Do not add columns as it will be already present in your datasource
Private Sub AddNewRowToGrid()
Dim dt As gridview1.DataSource
Dim NewRow As DataRow = dt.NewRow()
dt.Rows.Add(NewRow)
gridview1.DataSource = dt
gridview1.DataBind()
End Sub
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
AddNewRowToGrid()
End Sub
How do I delete multiple Rows in a GridView using a Checkbox, Delete button outside of the Grid, without going to database?
My purpose is to be able to delete multiple rows by SelectedCheckbox in the Gridview. After that, I use data show in gridview to make changes in database.
Dim dt As DataTable = ViewState("gridview")
Dim row As GridViewRow
For Each row In gridview.Rows
Dim SelectedRow As CheckBox = CType(row.FindControl("cbSelect"), CheckBox)
If SelectedRow.Checked Then
'gridview.rows(row.index).visible = false is not my case because those indexes are still there
End If
Next
I couldn't usegridview.rows(row.index).remove()/delete()
My 2nd option is store gridview to datatable by viewstate(). When i try to remove index in the FOR EACH loop, it showed error because after the 1st remove the datatable reindex.
Thanks for your help.
I got my 2nd option done by deleting row from bottom up.
I really appreciate If anyone could help me with my 1st option.
Dim dt As DataTable = ViewState("gridview")
For i As Integer = gridview.Rows.Count - 1 To 0 Step -1
Dim row As GridViewRow = gridview.Rows(i)
Dim SelectedRow As CheckBox = CType(row.FindControl("cbSelect"), CheckBox)
If SelectedRow.Checked Then
dt.Rows(i).Delete()
End If
Next
gridview.DataSource = dt
gridview.DataBind()
Yes, yes, delete each row from the bottom up. I believe it will be like this.
Private Sub Button_Delete_Checked_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button_Delete_Checked.Click
For Each row As DataGridViewRow In DataGridView1.Rows
If row.Cells("ToDelete").Value Then
MessageBox.Show(row.Cells("SomeText").Value & " will be deleted.")
End If
Next
End Sub
As for the Insert Into, this methodology should work fine.
Dim Con As OleDbConnection = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Music_Sales_Database.mdb;")
Dim Com As OleDbCommand
Dim SaleCode As Integer
Dim MusicID As String
Dim SubTotalPrice As Decimal
Dim Copies1 As Integer
Dim STR1 As String
SaleCode = 1
Com = New OleDbCommand
Com.Connection = Con
Connection.open()
For x As Integer = 0 To SalesDataGridView.Rows.Count - 1
MusicID = SalesDataGridView.Rows(x).Cells(0).Value
SubTotalPrice = SalesDataGridView.Rows(x).Cells(5).Value
Copies1 = SalesDataGridView.Rows(x).Cells(3).Value
STR1 = "INSERT INTO Sales(Sales_ID, Sales_Date, Copies, Music_ID, Staff_ID, Total_Price) VALUES (#Sales_ID, #Sales_Date, #Copies, #Music_ID, #Staff_ID, #Total_Price)"
Dim Comm As New OleDbCommand(STR1, Con)
Comm.Parameters.AddWithValue("#Sales_ID", SaleCode)
Comm.Parameters.AddWithValue("#Sales_Date", txtDateAndTime)
Comm.Parameters.AddWithValue("#Copies", Copies1)
Comm.Parameters.AddWithValue("#Music_ID", MusicID)
Comm.Parameters.AddWithValue("#Staff_ID", txtStaff_ID)
Comm.Parameters.AddWithValue("#Total_Price", SubTotalPrice)
Command.ExecuteNonQuery()
Comm.Dispose()
Next
Connection.Close()
Obviously, you need to modify this to suit your specific needs.
This is my interface, all the asp elements displayed are dynamically created! (Except the header)
Things I perform dynamically:
1. Create row with all those asp elements when page loads or button clicked.
2. I am able to lo populate DropDownList in "Items" column from database when it is created dynamically.
What I want to achieve?:
I want to load 'item code' 'item price' to appropriate text box when the item is selected from the DropDownList.
(Ex: when I click Laptop; it should load its item code and unit price to appropriate text box)
(Sorry for my bad programming approach, I'm beginner to asp.net)
'Page Load function'
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
If Not Page.IsPostBack or Page.IsPostBack Then
GenerateRows(numRows) 'Creates dynamic Table row and column with TextBox and DropDownList'
End If
End Sub
'Dynamic generating function, i have trimmed the code, to make it simple'
Protected Sub GenerateRows(numRows As Integer)
For i = 0 To numRows
Dim tRow As New TableRow
Dim tCode As New TableCell
Dim tItem As New TableCell
Dim lCode As New TextBox
Dim dList As New DropDownList
con = New Data.SqlClient.SqlConnection("Data Source=(localdb)\Projects;Initial Catalog=DataStore;Integrated Security=True")
con.Open()
query = "Select Item_Desc from Product"
cmd = New Data.SqlClient.SqlCommand(query, con)
cmd.ExecuteNonQuery()
dList.DataSource = cmd.ExecuteReader
dList.DataTextField = "Item_Desc"
dList.DataBind()
dList.Items.Insert(0, New ListItem("--- Select Product ---"))
dList.Height = 30
dList.AutoPostBack = True
dList.CausesValidation = True
AddHandler dList.SelectedIndexChanged, AddressOf Dynamic_Method
con.Close()
tCode.Controls.Add(lCode)
tItem.Controls.Add(dList)
tRow.Cells.Add(tCode)
tRow.Cells.Add(tItem)
Table1.Rows.Add(tRow) 'Table1 is not dynamic element'
Next
numRows += 1
ViewState("RowCount") = numRows 'numRows is Global variable'
End Sub
'This function is called when the selected index of DropDownList changes'
Protected Sub Dynamic_Method(ByVal sender As Object, ByVal e As EventArgs)
con = New Data.SqlClient.SqlConnection("Data Source=(localdb)\Projects;Initial Catalog=DataStore;Integrated Security=True")
con.Open()
Dim DDL As DropDownList = DirectCast(sender, DropDownList)
query = "Select * from Product where Item_Desc='" & DDL.SelectedValue.ToString & "'"
cmd = New Data.SqlClient.SqlCommand(query, con)
cmd.ExecuteNonQuery()
dr = cmd.ExecuteReader
If dr.HasRows = True Then
While (dr.Read)
ic = dr(0) 'dr(0) contains Item code of selected value which i need to add to textbox'
End While
End If
con.Close()
End Sub
hi what is my problem is in grid view after page loading i am entering some values in text box but after pressing the next page that page values are disappearing..
how can i save and retrieve the values into the grid view ..
i am able to save it in session but how can i past it into the currect page..
here is my code i am able to save it into the values but
after changing other page again entering into the same page how can i past the values into the corresponding page..
Protected Sub Gridview1_PageIndexChanging(ByVal sender As Object, ByVal e As GridViewPageEventArgs)
'Gridview1.PageIndex = e.NewPageIndex
'SetInitialRow()
Dim pageindex As Integer = Gridview1.PageIndex
Response.Write(Gridview1.PageIndex.ToString())
Dim d As Integer = Gridview1.PageCount
Dim texts As String() = New String(Gridview1.PageSize - 1) {}
Dim textBox As TextBox
Dim count As Integer = 0
For Each row As GridViewRow In Gridview1.Rows
textBox = DirectCast(row.FindControl("TextBox1"), TextBox)
If textBox IsNot Nothing Then
texts(count) = textBox.Text
Else
texts(count) = ""
End If
count += 1
Next
Session("one" + "pageindex") = texts
Gridview1.PageIndex= e.NewPageIndex
SetInitialRow()
'Dim sessionint As Integer = Session("page" + "pageindex")
'If Session("page" + "pageindex") IsNot Nothing Then
' Dim textBox1 As TextBox
' Dim texts1 As String() = DirectCast(Session("page" + "pageindex"), String())
' For i As Integer = 0 To Gridview1.Rows.Count - 1
' textBox1 = DirectCast(Gridview1.Rows(i).FindControl("textbox"), TextBox)
' textBox1.Text = texts(i)
' Next
'End If
End Sub
what is your datasource to bind to the gridview ?
These are the 2 ways that I have been doing...
Grab the whole data table and put it into ViewState("dataTable"). Do your filtering of rows and data from there.
Everytime you press 'Next Page', update the rows into the ViewState("dataTable").
Then rebind the gridview with the ViewState("dataTable").
Update the database directly when you press "Next Page".
I am trying to delete a row from a gridview (based on a condition) and then add than row to another gridview inside of the "master" gridview's RowDataBound event. Originally I did not know that in order to call .DeleteRow(i) you needed to have an "ondelete" event handler. However, since all the gridview's .DeleteRow method does is call this event handler, I am confused as to how to use it. Can someone please help point me in the right direction?
Protected Sub grdProduct_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles grdProduct.RowDataBound
' Grey out expired products
Dim row As GridViewRow
row = e.Row
Dim incomingDate As String
Dim incomingStatus As String = ""
incomingDate = row.Cells(3).Text.ToString()
incomingStatus = row.Cells(5).Text.ToString()
If (e.Row.RowType <> DataControlRowType.DataRow) Then
Exit Sub
End If
Try
Dim expDate As Date = incomingDate
If (expDate < DateTime.Today Or incomingStatus.Equals("D")) Then
'Create object for RowValues
Dim RowValues As Object() = {"", "", "", "", "", ""}
'Create counter to prevent out of bounds exception
Dim i As Integer = row.Cells.Count
'Fill row values appropriately
For index As Integer = 0 To i - 1
RowValues(index) = row.Cells(index).Text
Next
'create new data row
dProdRow = dProdtable.Rows.Add(RowValues)
dProdtable.AcceptChanges()
grdProduct.DeleteRow(e.Row.RowIndex)
End If
Catch ex As Exception
End Try
End Sub
Protected Sub grdProduct_Delete(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewDeleteEventArgs) Handles grdProduct.RowDeleting
'Not sure what to do here
End Sub
The best way to do this is to manipulate this at the datasource level rather than manipulating the UI components themselves.
For example:
if(!IsPostback)
{
DataTable one = ...
DataTable two = ...
var removeRows = (from c in one.AsEnumerable()
where c.Field<DateTime>("incomingDate")< incomingDate ||
c.Field<string>("incomingStatus")=="D"
select c).ToList();
for(var item in removeRows)
{
two.ImportRow(item);
}
//now delete from initial table
foreach(var item in removeRows)
{
one.Rows.Remove(item);
}
//Now bind both grids
grid1.DataSource=one;
grid1.DataBind();
grid2.DataSource=two;
grid2.DataBind();
}
Update - Sample toy program in VB.NET Hopefully you can adapt it to your situation.
Sub Main
Dim one As New DataTable()
one.Columns.Add("one", GetType(Integer))
For i As Integer = 0 To 9
Dim r As DataRow = one.NewRow()
r.ItemArray = New Object() {i}
one.Rows.Add(r)
Next
Dim two As New DataTable()
two.Columns.Add("one", GetType(Integer))
For i As Integer = 0 To 9
Dim r As DataRow = two.NewRow()
r.ItemArray = New Object() {i}
two.Rows.Add(r)
Next
Dim removeRows = (From c In one.AsEnumerable() Where c.Field(Of Integer)("one") = 5).ToList()
For Each item As DataRow In removeRows
two.ImportRow(item)
Next
For Each item As DataRow In removeRows
one.Rows.Remove(item)
Next
End Sub
I just realized that you are using VB.NET. You should be able to translate the above from C# to VB.NET. The general idea is there, anyway.