Editing a Gridview w/o using an SqlDatasource using VB.Net - asp.net

I developed the following code for editing a GridView (following a tutorial written in C#), It goes into edit mode, but my edits do not take effect, here is my code:
aspx.vb code:
Imports System.Data
Imports System.Data.SqlClient
Imports System.Globalization
Partial Class MemberPages_editOutage
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
If Not IsPostBack Then
BindGrid()
End If
End Sub
Private Sub BindGrid()
Dim dt As New DataTable()
Dim connection As New SqlConnection("server='\SQLEXPRESS'; trusted_connection='true'; Database='OutagesMgt_db'")
Try
connection.Open()
Dim sqlStatement As String = "SELECT OutageDetailId, LocationName, Description, DetailDescription, CreateDate, StatusId FROM OutageDetail WHERE StatusId='1' ORDER BY CreateDate DESC"
Dim cmd As New SqlCommand(sqlStatement, connection)
Dim sqlDa As New SqlDataAdapter(cmd)
sqlDa.Fill(dt)
If dt.Rows.Count > 0 Then
MyDataGrid.DataSource = dt
MyDataGrid.DataBind()
End If
Catch ex As System.Data.SqlClient.SqlException
Dim msg As String = "Fetch Error:"
msg += ex.Message
Throw New Exception(msg)
Finally
connection.Close()
End Try
End Sub
'edit command
Protected Sub MyDataGrid_RowEditing(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewEditEventArgs) Handles MyDataGrid.RowEditing
'turn to edit mode
MyDataGrid.EditIndex = e.NewEditIndex
'Rebind the GridView to show the data in edit mode
BindGrid()
End Sub
'cancel command
Protected Sub MyDataGrid_RowCancelingEdit(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCancelEditEventArgs) Handles MyDataGrid.RowCancelingEdit
' switch back to edit default mode
MyDataGrid.EditIndex = -1
'Rebind the GridView to show the data in edit mode
BindGrid()
End Sub
'Update Function
Private Sub UpdateRecord(ByVal SOutageDetailId As String, ByVal SDescription As String, ByVal SDetailDescription As String, ByVal SCreateDate As String, ByVal SstatusId As String)
Dim connection As New SqlConnection("server='\SQLEXPRESS'; trusted_connection='true'; Database='OutagesMgt_db'")
Dim sqlStatement As String = String.Empty
sqlStatement = "UPDATE OutageDetail SET #OutageDetailId = #OutageDetailId, LocationName = #LocationName, " & _
"Description = #Description, DetailDescription= #DetailDescription, " & _
"CreateDate = #CreateDate, StatusId = #StatusId WHERE OutageDetailId = #OutageDetailId"
connection.Open()
Dim cmd As New SqlCommand(sqlStatement, connection)
cmd.Parameters.Add(New SqlParameter("#OutageDetailId", SOutageDetailId))
cmd.Parameters.Add(New SqlParameter("#LocationName", SDescription))
cmd.Parameters.Add(New SqlParameter("#Description", SDescription))
cmd.Parameters.Add(New SqlParameter("#DetailDescription", SDetailDescription))
cmd.Parameters.Add(New SqlParameter("#CreateDate", SCreateDate))
cmd.Parameters.Add(New SqlParameter("#StatusId", SstatusId))
cmd.CommandType = CommandType.Text
cmd.ExecuteNonQuery()
' MyDataGrid.EditIndex = -1
connection.Close()
BindGrid()
End Sub
'update command
Protected Sub MyDataGrid_RowUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewUpdateEventArgs) Handles MyDataGrid.RowUpdating
'Accessing Edited values from the GridView
Dim SOutageDetailId As String = MyDataGrid.Rows(e.RowIndex).Cells(0).Text
Dim SDescription As String = MyDataGrid.Rows(e.RowIndex).Cells(1).Text
Dim SDetailDescription As String = MyDataGrid.Rows(e.RowIndex).Cells(2).Text
Dim SCreateDate As String = MyDataGrid.Rows(e.RowIndex).Cells(3).Text
Dim SstatusId As String = MyDataGrid.Rows(e.RowIndex).Cells(4).Text
'Call the function to update the GridView
UpdateRecord(SOutageDetailId, SDescription, SDetailDescription, SCreateDate, SstatusId)
MyDataGrid.EditIndex = -1
'Rebind Gridview to reflect changes made
BindGrid()
End Sub
End Class
aspx code:
<asp:GridView id="MyDataGrid" runat="server"
Width="750px"
CssClass="gridViewEdit"
BackColor="White"
BorderColor="Black"
CellPadding="3"
Font-Name="Verdana"
Font-Size="8pt"
HeaderStyle-BackColor="#FFFFFF"
OnEditCommand="MyDataGrid_RowEditing"
OnCancelCommand="MyDataGrid_RowCancelingEdit"
OnUpdateCommand="MyDataGrid_RowUpdating"
DataKeyField="OutageDetailId"
Font-Names="Verdana">
<Columns>
<asp:CommandField ShowEditButton="True" EditText="Edit" CancelText="Cancel" UpdateText="Update" />
</Columns>
<HeaderStyle BackColor="White"></HeaderStyle>
</asp:GridView>
Could someone shed some light on what I am missing please.

The moment you hit the Edit, you go to get the ID of the line that must be update, and you get it from this line
Dim SOutageDetailId As String = MyDataGrid.Rows(e.RowIndex).Cells(0).Text
but on page load you have set
If Not IsPostBack Then
BindGrid()
End If
so on the post back, the grid up to the point you try to get the id from the cell, is empty.
Two ways, ether give again the data on post back, and make DataBind right after the update, or get the Index of the Grid View to make the Update, and not take the Cell.
For example, I will change your code to:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
BindGrid()
End Sub
Private Sub BindGrid()
Dim dt As New DataTable()
Dim connection As New SqlConnection("server='\SQLEXPRESS'; trusted_connection='true'; Database='OutagesMgt_db'")
Try
connection.Open()
Dim sqlStatement As String = "SELECT OutageDetailId, LocationName, Description, DetailDescription, CreateDate, StatusId FROM OutageDetail WHERE StatusId='1' ORDER BY CreateDate DESC"
Dim cmd As New SqlCommand(sqlStatement, connection)
Dim sqlDa As New SqlDataAdapter(cmd)
sqlDa.Fill(dt)
If dt.Rows.Count > 0 Then
MyDataGrid.DataSource = dt
If Not IsPostBack Then
MyDataGrid.DataBind()
End If
End If
Catch ex As System.Data.SqlClient.SqlException
Dim msg As String = "Fetch Error:"
msg += ex.Message
Throw New Exception(msg)
Finally
connection.Close()
End Try
End Sub
[*] Assuming that you do not have other bugs on sql...

Related

How to get values from an object in sql query in asp.net vb.net

I want to run a select command and I've a dropdownlist populated with database table names. How to write the select command? Here is my code
Dim da As New OdbcDataAdapter("select table_name from INFORMATION_SCHEMA.tables WHERE TABLE_TYPE = 'BASE TABLE' and table_schema='public'", dbcon.con)
Dim dt As New DataTable
da.Fill(dt)
ddltablename.DataSource = dt
ddltablename.DataTextField = "table_name"
ddltablename.DataValueField = "table_name"
ddltablename.DataBind()
End Sub
Protected Sub btndump_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btndump.Click
Dim da As New OdbcDataAdapter("select * from ddltablename.SelectedItem.tostring", dbcon.con)
Dim ds As New DataSet
da.Fill(ds)
End Sub
Sure, lets drop in your combo box, and then a gridview.
like this:
<asp:DropDownList ID="cboTables" runat="server" Height="31px" Width="179px"
DataTextField ="table_name"
DataValueField ="table_name" Rows="50" >
</asp:DropDownList>
<asp:Button ID="cmdShowTables" runat="server" Text="Show Selected table" Width="175px" style="margin-left:25px"/>
<br />
<br />
<asp:GridView ID="GridView1" runat="server"></asp:GridView>
And our code can thus be:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
Dim strSQL As String =
"SELECT table_name from INFORMATION_SCHEMA.tables " &
"WHERE TABLE_TYPE = 'BASE TABLE' ORDER BY table_name"
cboTables.DataSource = MyRst(strSQL)
cboTables.DataBind()
End If
End Sub
Protected Sub cmdShowTables_Click(sender As Object, e As EventArgs) Handles cmdShowTables.Click
Dim rst As New DataTable
rst = MyRst("SELECT * from " & cboTables.SelectedItem.Value)
'GridView1.DataSource
GridView1.DataSource = rst
GridView1.DataBind()
End Sub
Function MyRst(strSQL As String) As DataTable
Dim rstData As New DataTable
Using conn As New OdbcConnection(My.Settings.TEST3ODBC)
Using cmdSQL As New OdbcCommand(strSQL, conn)
conn.Open()
rstData.Load(cmdSQL.ExecuteReader)
End Using
End Using
Return rstData
End Function
Output:
Or you can say do this:
Dim rst As New DataTable
rst = MyRst("SELECT * from " & cboTables.SelectedItem.Value)
For Each OneRow as DataRow in rst.rows
debug.print ("Hotel Name = " & OneRow("HoteName").ToString())
Next
Probably something like this:
Protected Sub btndump_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btndump.Click
Dim tableName = ddltablename.SelectedItem.ToString();
' It would be prudent to create a function to verify table names against a
' whitelist before sending it, since generating a sql command
' using string concatenation carries the risk of sql injection
Dim da As New OdbcDataAdapter("select * from " & tableName & ";", dbcon.con)
Dim ds As New DataSet
da.Fill(ds)
End Sub
Getting the value of your control, ddltablename, has to be done in the application context, not within the SQL command.

asp.net DropDownList postback not executing method on first postback

I'm facing very un natural problem suddenly. I have DropDownList with autopostback is true. Postback executes a method which populates other things onpage according to selection. Now When I select any value first time from that dropdown then page gets postback but nothing get populate but from second time it works fine. Even I put breakpoint on that dropdown & it's not even hitting breakpoint for first postback.
<asp:DropDownList ID="ClientCode" runat="server" ClientIDMode="Static" CssClass="field-pitch" AutoPostBack="true"></asp:DropDownList>
Private Sub ClientCode_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ClientCode.SelectedIndexChanged
Me.populateConsignerDetails()
End Sub
Private Sub populateConsignerDetails()
Try
Dim str As String = "SELECT * FROM clientsDetails WHERE clientID = #clientID"
con.Open()
Dim cmd As New MySqlCommand(str, con)
cmd.Parameters.AddWithValue("#clientID", ClientCode.SelectedItem.ToString)
Dim da As New MySqlDataAdapter(cmd)
Dim dt As New DataTable
da.Fill(dt)
con.Close()
Dim payingParty As String = String.Empty
If dt.Rows.Count > 0 Then
consignerName.Text = dt.Rows(0)("clientName").ToString
consignerAddress.Text = dt.Rows(0)("companyAddress").ToString
consignerMobile1.Text = dt.Rows(0)("contactNumber1").ToString
consignerCity.Text = dt.Rows(0)("city").ToString
consignerState.Text = dt.Rows(0)("state").ToString
consignerPinCode.Text = dt.Rows(0)("pinCode").ToString
End If
Catch ex As Exception
Response.Write(ex)
End Try
End Sub
Update
Private Sub myadmin_shipment_details2_Load(sender As Object, e As EventArgs) Handles Me.Load
If Not Me.IsPostBack Then
populateClient()
End If
End Sub
Private Sub populateClient()
Using conn As New MySqlConnection()
conn.ConnectionString = ConfigurationManager _
.ConnectionStrings("conio").ConnectionString()
Using cmd As New MySqlCommand()
cmd.CommandText = "Select * from clientsDetails where status = 'active'"
cmd.Connection = conn
conn.Open()
Using sdr As MySqlDataReader = cmd.ExecuteReader()
While sdr.Read()
Dim item As New ListItem()
item.Text = sdr("clientID").ToString()
item.Value = sdr("ClientName").ToString()
ClientCode.Items.Add(item)
End While
End Using
conn.Close()
End Using
End Using
End Sub

VB.Net Dropdownlist Value is always 1

I got a Dropdownlist filled from a Database, using the ID from the Database as ValueField but it just doesn't work
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim strConnection As String = "DEMOString"
connection = New OleDbConnection(strConnection)
connection.ConnectionString = strConnection
connection.Open()
Dim dtb As DataTable
Dim strSql As String = "SELECT * FROM Personen"
dtb = New DataTable()
Using dad As New OleDbDataAdapter(strSql, connection)
dad.Fill(dtb)
End Using
dtb.Columns.Add("Fullname", GetType(String), "Vorname + ' ' + Nachname")
ddlName.Items.Clear()
ddlName.DataSource = dtb
ddlName.DataTextField = "Fullname"
ddlName.DataValueField = "sozNr"
ddlName.DataBind()
connection.Close()
End Sub
When I try using ddlName.SelectedItem.Value later i get 1 for every Item.
The Using Code
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim dateString As String = tbDate.Text
Dim name As String = ddlName.SelectedItem.Text
Dim des As String = tbDescription.Text
MsgBox(ddlName.SelectedItem.Value)
You don't have to DataBind the DropDownList on every postback if viewstate is enabled(default). That will overwrite all changes like the SelectedIndex. Instead put the code in Page_Load in a Not Is PostBack check:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
Dim strConnection As String = "DEMOString"
connection = New OleDbConnection(strConnection)
connection.ConnectionString = strConnection
connection.Open()
Dim strSql As String = "SELECT * FROM Personen"
Dim dtb As New DataTable()
Using dad As New OleDbDataAdapter(strSql, connection)
dad.Fill(dtb)
End Using
dtb.Columns.Add("Fullname", GetType(String), "Vorname + ' ' + Nachname")
ddlName.DataSource = dtb
ddlName.DataTextField = "Fullname"
ddlName.DataValueField = "sozNr"
ddlName.DataBind()
connection.Close()
End If
End Sub
Side-Note: you should also not reuse the connection. Instead create, initialize and close it in the method where you use it, best by using the Using-statement which also ensures that it get's disposed/closed in case of an error.

Program won't give me the right Sum

I want to get the sum of the selected items in the listbox and display them in a label but i am always getting 0,i also want to put the selected items in another label too which is also not working.
Here is what the code look like:
Dim sum As Integer
Dim Items1 As String = "None"
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
Label2.Text = Request.QueryString("Name").ToString()
Dim connetionString As String = Nothing
Dim connection As SqlConnection
Dim command As SqlCommand
Dim adapter As New SqlDataAdapter()
Dim ds As New DataSet()
Dim sql As String
connetionString = "Data Source=.;Initial Catalog=Shop;integrated security=true"
sql = "select PhoneName,PhonePrice from SmartPhones"
connection = New SqlConnection(connetionString)
connection.Open()
command = New SqlCommand(sql, connection)
adapter.SelectCommand = command
adapter.Fill(ds)
adapter.Dispose()
command.Dispose()
connection.Close()
ListBox1.DataSource = ds.Tables(0)
ListBox1.DataTextField = "PhoneName"
ListBox1.DataValueField = "PhonePrice"
ListBox1.DataBind()
End Sub
code where the display should happen:
Protected Sub Button2_Click(sender As Object, e As EventArgs) Handles TotalPrice.Click
sum = 0 'reset sum to 0
For Each i As Integer In ListBox1.GetSelectedIndices
Dim CurrentItem As ListItem = ListBox1.Items(i)
sum = sum + CInt(CurrentItem.Value)
Items1 = Items1 + " , " + CStr(CurrentItem.Text)
Next
Label3.Text = Items1
Label1.Text = sum
End Sub
Here is the page Design and the Page On the web Respectively:
PhoneName is of type varchar in database & PhonePrice is of type integer (Both Filled correctly).
ListBox code:
<asp:ListBox ID="ListBox1" runat="server" SelectionMode="Multiple" ></asp:ListBox>
What's the reason that the code won't give me the desired result?
What is happening is that when you click TotalPrice a postback is performed (What is a postback?). If you look at the ASP.NET page lifecycle you will see that the Load event happens before the postback event handling (e.g. your Sub Button2_Click).
So, you click the button, it runs the Me.Load handler and... your list is reset before the click handler gets a chance to run.
There is a property you can check to see if the page is running as a result of a postback: Page.IsPostBack.
So all you need to do is check it to see if you need to populate the list:
Sub FillItemsList()
Dim connectionString As String = "Data Source=.;Initial Catalog=Shop;integrated security=true"
Dim dt As New DataTable()
Using connection As New SqlConnection(connectionString)
Dim sql As String = "SELECT PhoneName,PhonePrice FROM SmartPhones"
Using adapter As New SqlDataAdapter(sql, connection)
adapter.Fill(dt)
End Using
End Using
ListBox1.DataSource = dt
ListBox1.DataTextField = "PhoneName"
ListBox1.DataValueField = "PhonePrice"
ListBox1.DataBind()
End Sub
Private Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
Label2.Text = Request.QueryString("Name").ToString()
If Not Page.IsPostBack Then
FillItemsList()
End If
End Sub

GridView1_PageIndexChanging not changing when index changing

I am trying to display 50 at a time. It should activate when the "Page Index" is changed. The original Gridview works and has more than 1000 entries. The GridView1_PageIndexChanging or GridView1.PageIndex = e.NewPageIndex is not functioning.
Here is my code:
<asp:GridView ID="GridView1" runat="server" AllowPaging="True" PageSize="50" OnPageIndexChanging="GridView1_PageIndexChanging">
</asp:GridView>
Protected Sub GridView1_PageIndexChanging(ByVal sender As Object, ByVal e As GridViewPageEventArgs) Handles GridView1.PageIndexChanging
GridView1.PageIndex = e.NewPageIndex
Dim connStr, cmdStr As String
Dim myDataSet As New DataSet
Dim dt As New DataTable()
connStr = "connection string works"
cmdStr = "SELECT * FROM table1;"
Try
Using conn As New SqlConnection(connStr)
Using cmd As New SqlCommand(cmdStr, conn)
conn.Open()
cmd.ExecuteNonQuery()
Using myDataAdapter As New SqlDataAdapter(cmd)
myDataAdapter.Fill(myDataSet)
dt = myDataSet.Tables(0)
Dim filteredSet = dt.AsEnumerable().Skip((GridView1.PageIndex - 1) * 50)
GridView1.DataSource = filteredSet
GridView1.DataBind()
End Using
conn.Close()
cmd.Dispose()
conn.Dispose()
End Using
End Using
Catch ex As Exception
End Try
End Sub
The GridView will handle your paging for you, if you let it. You don't need to filter the query yourself. I have a couple of suggestions:
Centralize your databinding code
Put all that databinding code in a centralized function. This will make your PageIndexChanging event look cleaner, and reduce the risk of typo errors (if you have to duplicate that code elsewhere). It should be something like this:
Private Sub BindGrid()
Dim connStr, cmdStr As String
Dim myDataSet As New DataSet
Dim dt As New DataTable()
connStr = "connection string works"
cmdStr = "SELECT * FROM table1;"
Try
Using conn As New SqlConnection(connStr)
Using cmd As New SqlCommand(cmdStr, conn)
conn.Open()
cmd.ExecuteNonQuery()
Using myDataAdapter As New SqlDataAdapter(cmd)
myDataAdapter.Fill(myDataSet)
dt = myDataSet.Tables(0)
GridView1.DataSource = dt
GridView1.DataBind()
End Using
conn.Close()
End Using
End Using
Catch ex As Exception
End Try
End Sub
Note: I took out your calls to Dispose, as they were redundant (that's what the Using block does)
Update your PageIndexChanging code to call that sub
Now you can have a cleaned up function for the paging:
Protected Sub GridView1_PageIndexChanging(ByVal sender As Object, ByVal e As GridViewPageEventArgs) Handles GridView1.PageIndexChanging
GridView1.PageIndex = e.NewPageIndex
BindGrid()
End Sub
Optimization: cache your database call in some way
You shouldn't need to retrieve 1,000+ rows from your database every time you page your GridView. Put the DataTable in a Session variable the first time you load the Grid (in Page_Load, I imagine):
Session("myGridViewData") = dt
Then grab it out of there any time you need it again (such as during paging):
Protected Sub GridView1_PageIndexChanging(ByVal sender As Object, ByVal e As GridViewPageEventArgs) Handles GridView1.PageIndexChanging
GridView1.PageIndex = e.NewPageIndex
Gridview1.DataSource = CType(Session("myGridViewData"), DataTable)
GridView1.DataBind()
End Sub

Resources