I have a Gridview filled by a dataTable, filled by a DataAdapter. That's how grid is initially loaded in Page_Load.
To add a search funcionality, I make the same but passing TextBox.Text as parameter to the SELECT... LIKE ... statement.
To add an edit funcionality(a button in every row) I need the previous data in the dataTable, and if I performed a search before editing I need only the result of the search in my dataTable.
The problem is, I don't know how to keep its value alive (persistent), and dataTable has 0 columns when I press teh edit button, so it doesn't display anything to edit.
I guess it happens because I'm using Using, and dataTable is probably getting cleaned after End Using.
In that case, whta can I do to fix it? I thought removing miconn.Close() but it doesn't solve anything, in fact, I don't know if connection is still open after End Using.
Code:
Dim con As New Connection
Dim table As New DataTable()
Private Sub fill_grid()
Using miconn As New SqlConnection(con.GetConnectionString())
Dim sql As String = "SELECT area,lider_usuario FROM AREA"
Using command As New SqlCommand(sql, miconn)
Using ad As New SqlDataAdapter(command)
ad.Fill(table)
GridView1.DataSource = table
GridView1.DataBind()
'miconn.Close()
End Using
End Using
End Using
End Sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
fill_grid()
End If
End Sub
Protected Sub btnSearch_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSearch.Click
Dim miCon As New Connection
Using miconn As New SqlConnection(miCon.GetConnectionString())
Dim sql As String = "SELECT area,lider_usuario FROM AREA WHERE area LIKE #area"
Using command As New SqlCommand(sql, miconn)
command.Parameters.Clear()
command.Parameters.Add("#area", SqlDbType.VarChar).Value = "%" + TextBox1.Text + "%"
Using ad As New SqlDataAdapter(command)
ad.Fill(table)
GridView1.DataSource = table
GridView1.DataBind()
'miconn.Close()
End Using
End Using
End Using
End Sub
Protected Sub EditRow(ByVal sender As Object, ByVal e As GridViewEditEventArgs)
GridView1.EditIndex = e.NewEditIndex
GridView1.DataSource = table
GridView1.DataBind()
End Sub
Protected Sub CancelEditRow(ByVal sender As Object, ByVal e As GridViewCancelEditEventArgs)
GridView1.EditIndex = -1
GridView1.DataSource = table
GridView1.DataBind()
End Sub
BindGrid()
{
var dt = YourMethodReturningDatatable();
ViewState["Table"] = dt;
grid.DataSource = ViewState["Table"];
grid.Databind();
}
page_load
{
if(not ispostback) // not because my 1 key stopped working.
{
BindGrid();
}
}
I would suggest you to make two different functions for filling the data table and binding it. Call the filling function before the !IsPostBack condition and do the binding inside the condition. Here is the sample code:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim table as new DataTable
table = GetData() 'The function that would return a data table
If Not IsPostBack Then
GridView1.DataSource = table
GridView1.DataBind()
End If
End Sub
Private Function GetData() As DataTable
Using miconn As New SqlConnection(con.GetConnectionString())
Dim sql As String = "SELECT area,lider_usuario FROM AREA"
Using command As New SqlCommand(sql, miconn)
Using ad As New SqlDataAdapter(command)
ad.Fill(table)
GetData = table
miconn.Close()
End Using
End Using
End Using
End function
Hope it helps.
Related
I am using ASP.NET with VB.NET and I want the user add several row to data table.
I am trying to add multi row into data table in run time by (textboxes, rad combo box and check box).
I add first row second and third row.
But when I present the data table its show only the last row I enter
so the table contain only one row.
How do I keep all row in data table not only one row? I tried everything please help.
This is my code:
Dim dcItemID = New DataColumn("ItemID", GetType(Int32))
Dim dcUnit = New DataColumn("UnitID", GetType(Int32))
Dim ItemPrice = New DataColumn("ItemPrice", GetType(Int32))
Dim sellprice = New DataColumn("SellPrice", GetType(Int32))
dt.Columns.Add(dcItemID)
dt.Columns.Add(dcUnit)
dt.Columns.Add(ItemPrice)
dt.Columns.Add(sellprice)
dt.Rows.Add(Convert.ToInt32(rcItemName.SelectedValue), Convert.ToInt32(rcUnitID.SelectedValue), tbItemPrice.Text, tbSellprice.Text)
thank u all i found the answer
if any one interested this is my solution :
Public Class WebForm1
Inherits System.Web.UI.Page
Private dt As DataTable = New DataTable()
Private dr As DataRow = Nothing
Protected Sub btnSaved_Click(sender As Object, e As EventArgs) Handles btnSaved.Click
If ViewState("table") IsNot Nothing Then
dt = CType(ViewState("table"), DataTable)
End If
dr = dt.NewRow()
dr("ItemPrice") = tbItemPrice.Text
dr("SellPrice") = tbSellprice.Text
' dr("Product_Amount") = txtAmount.Text
dt.Rows.Add(dr)
ViewState("table") = dt
GridView1.DataSource = dt
GridView1.DataBind()
End Sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
dt.Columns.Add("ItemPrice")
dt.Columns.Add("SellPrice")
End Sub
End Class
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
I've been reading posts and articles and just getting a little confused and consequently burning through time I don't have at the moment
Can someone look at my code and tell me where I've gone wrong?
Partial Class PayerContacts
Inherits System.Web.UI.Page
Dim connStrDRContacts As String = ConfigurationManager.ConnectionStrings("DRContacts_SQL").ConnectionString
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
navBuild()
End Sub
Protected Sub Page_Init(sender As Object, e As EventArgs) Handles Me.Init
If IsPostBack Then
LoadContacts(ViewState("objSender"))
End If
End Sub
Private Function navBuild() As Integer
Dim SQLstrDRs As String = "SELECT * FROM DRList"
Dim DbConnDRs As SqlConnection = New SqlConnection(connStrDRContacts)
DbConnDRs.Open()
Dim dtDRsTemp As New DataTable
Dim SQLAdapterDRs As New SqlDataAdapter(SQLstrDRs, DbConnDRs)
SQLAdapterDRs.Fill(dtDRsTemp)
'Loop through each row of the DataView to create HTML table data
Dim NewTableRow As New TableRow
For Each row As DataRow In dtDRsTemp.Rows
'CREATE table with button to display contacts related to client (one to many)
Dim NewTableButton As LinkButton = New LinkButton
NewTableButton.ID = "btnDRName" & NewTableText
NewTableButton.ViewStateMode = UI.ViewStateMode.Enabled
AddHandler NewTableButton.Click, AddressOf LoadContacts
Next
Return 0
End Function
Protected Sub LoadContacts(sender As Object, e As EventArgs)
Dim LoopCount As Integer = 0
Dim SQLstrLoadTable As String = "SELECT * FROM ContactList WHERE DRVendor = '" & sender.Text.ToString & "'"
and so on....
SQLAdapterLoadTable.Fill(dtLoadTableTemp)
Dim NewTableRow As New TableRow
For Each row As DataRow In dtLoadTableTemp.Rows
'CREATE Accordion to display data
NewAccordion.ID = "ContactAccordion" & LoopCount
NewAccordion.Visible = True
blah, blah...
'SET Pane
NewAccordionPane.HeaderContainer.ID = "PaneHeader" & LoopCount
NewAccordionPane.ContentContainer.ID = "PaneContent" & LoopCount
'CREATE button to open ModalPopup to EDIT each record
Dim imgGear As New ImageButton
imgGear.ID = "btnGear" & row!ID.ToString
imgGear.ViewStateMode = UI.ViewStateMode.Enabled
AddHandler imgGear.Click, AddressOf EditRecord
'LOAD Pane
NewAccordionPane.HeaderContainer.Controls.Add(NewHeaderTable)
NewAccordionPane.ContentContainer.Controls.Add(New LiteralControl(NewTableText))
ViewState("objSender") = sender
End Sub
Protected Sub EditRecord(ByVal sender As Object, ByVal e As EventArgs)
'Open ModalPopup to edit record
popup.Show()
pnlAddEdit.Visible = True
End Sub
End Class
The Infinities Loop articles on ViewState and Dynamic Controls should really be read by every Webforms developer: -
http://mocha.mojoskins.com/SharedFiles/Download.aspx?pageid=566&mid=786&fileid=38
http://weblogs.asp.net/infinitiesloop/TRULY-Understanding-Dynamic-Controls-_2800_Part-1_2900_
The examples are in C# but you should be able to figure out what's going on, it's the same base class library after all.
I am learning ASP.Net development & trying to create Web application where ListView data should get filter selection done in ComboBox. I have made ListView & bind it with my database table & tried to put ComboBox filter but getting this error
(System.Web.HttpException: Request is not available in this context) in output .
VB Code
Imports System.Data
Imports System.Data.SqlClient
Imports System.Configuration
Partial Class VB
Inherits System.Web.UI.Page
Dim query As String
Dim strArea As String = Request.QueryString("Country")
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
If Not Me.IsPostBack Then
Me.BindListView()
End If
End Sub
Private Sub BindListView()
Dim constr As String = ConfigurationManager.ConnectionStrings("constr").ConnectionString
Using con As New SqlConnection(constr)
Using cmd As New SqlCommand()
cmd.CommandText = "SELECT CustomerId, ContactName, Country FROM Customers"
cmd.Connection = con
Using sda As New SqlDataAdapter(cmd)
Dim dt As New DataTable()
sda.Fill(dt)
lvCustomers.DataSource = dt
lvCustomers.DataBind()
End Using
End Using
End Using
End Sub
Protected Sub OnPagePropertiesChanging(sender As Object, e As PagePropertiesChangingEventArgs)
TryCast(lvCustomers.FindControl("DataPager1"), DataPager).SetPageProperties(e.StartRowIndex, e.MaximumRows, False)
Me.BindListView()
End Sub
Protected Sub country_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles country.SelectedIndexChanged
Try
If country.SelectedValue <> "All" Then
query = "Select CutomerId, Contact Name, Country from Customers where Country like '%" + strArea + "%' order by rank;"
End If
Dim cmd As New SqlCommand(query)
Dim da As New SqlDataAdapter(cmd)
Dim table As New DataTable
Catch ex As Exception
End Try
End Sub
End Class
Request read-only property belongs to Page class and inherited class members are available only within the members of the class which inherits it(VB in your case). Change your code like this:-
Partial Class VB
Inherits System.Web.UI.Page
Dim query As String
Dim strArea As String = String.Empty
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
If Not Me.IsPostBack Then
Me.BindListView()
End If
strArea = Request.QueryString("Country")
End Sub
Also, Please note it will be better to check if any value exists within your query string variable before assigning it.
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