Hey all, i am new at everything VB.net/ASP.net so i need some help with a problem i am currently having.
I have an ASCX.vb page that lets the user choose someone from a table. Once they do select someone, the page reloads with that persons information into another table below that one where they can submit an order for that person or remove that person.
Problem being is that i wanted to store the users ID that are selected but it seems that everytime the page reloads to show an update, it dim's my array again back to default.
This is my code once they choose a user:
Namespace prog.Controls
Partial Public Class progReportGrid
etc....
Public strIDArray() As String = {"0000770000"} 'Just a dummy place holder
Private Sub gvData_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles gvData.RowCommand
Dim idIndexNumber As Integer = Array.IndexOf(strIDArray, strID)
For i As Integer = 0 To strIDArray.Length - 1
System.Diagnostics.Debug.WriteLine(strIDArray(i))
Next
If idIndexNumber = -1 Then
ReDim Preserve strIDArray(strIDArray.Length)
strIDArray(strIDArray.Length) = strID
RaiseEvent EmployeeSelected(Me, New ESEventArgs(strID))
End If
End Sub
So everytime to page reloads the Public strIDArray() As String = {"0000770000"} gets called again and, of course, clears anything that was saved to it other than 0000770000.
How can i keep it from doing this?
UPDATE
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
'do what?
End If
End Sub
David
Perhaps you have a misunderstanding with the stateless model of a web application. Anything that is not stored in the ViewState or Session or a shared application variable will NOT persist through postbacks.
This means that when you declare your
Public strIDArray() As String
as a standard variable, it will be re initialized every time the page posts back.
For example, here's a simple flow of how this works:
The user opens their browser and opens up your aspx web page.
The request goes to your server, and all the controls including progReportGrid are instantiated as new instances and added to the page. (this is where your variable gets set to its original value every time)
A bunch of events are fired, including the Me.Load event
Controls that were added to the page are asked to generate their HTML
The HTML gathered from all the controls on the page is sent back to the user
So because your controls are all re-instantiated every post back, class variables like strIDArray are pretty much thrown out after the page is sent to the user.
Instead, if you want the page to remember what value the array had last postback and add more to it next postback, you have to use either ViewState, or Session.
For example:
Private Property StrIDArray() As String()
Get
If ViewState("StrIDArray") Is Nothing
ViewState("StrIDArray") = New String() {"0000770000"}
Return ViewState("StrIDArray")
End Get
Set(ByVal value As String())
ViewState("StrIDArray") = value
End Set
End Property
Now if you used this property instead of your variable, you could manipulate that array and as long as the user is on that page, the value of that array will persist across postbacks.
Use the Page.IsPostBack property in your Page_Load method.
This property is false for the first time the page loads and false for every postback afterwards.
If you set your default value strIDArray() = {"0000770000"} within If (Page.IsPostBack <> true) then it will not get reset on the postback.
EDIT : My VB syntax is VERY shaky but let me try it out
Partial Public Class EARNReportGrid
Begin
Public strIDArray() As String // DO NOT INITIALIZE it here. ONLY DECLARE IT
.....
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
//INITIALIZE the ARRAY
strIDArray = New String(){"00007700000"}
End If
End Sub
......
End
Related
Using vb.net 4.5 and Telerik 2017.2.711.45 (Q2)
I am trying to get radgrid filter expressions and a public string variable to persist across postbacks.
With EnableViewState=FALSE, radgrid filter expressions do not persist through postback, however a public string variable (stringVar) does persist.
When I set EnableViewState=TRUE the filter expressions in radgrid do persist, however it causes stringVar to not persist.
From my understanding of ViewState, it makes no sense that setting EnableViewState=TRUE would cause stringVar to not persist across postbacks. I would love to know why this is occurring and what I could do to resolve this.
EDIT:
The highlighted Line is where an error would be thrown because ReportTitle no longer has a value.
Partial Class displayxslgrid
Public ReportTitle As String
Public ReportsDB As reportDataBase
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Page.EnableViewState = True
Reports = New reportDataBase.Global_Functions(System.Web.HttpContext.Current)
End Sub
Protected Sub RadGrid1_NeedDataSource(sender As Object, e As Telerik.Web.UI.GridNeedDataSourceEventArgs) Handles RadGrid1.NeedDataSource
Call BindRadGrid1()
End Sub
Protected Sub RadGrid1_ItemCommand(ByVal source As Object, ByVal e As Telerik.Web.UI.GridCommandEventArgs) Handles RadGrid1.ItemCommand
Dim strReportTitle As String
Select Case e.CommandName
Case RadGrid.ExportToExcelCommandName, RadGrid.ExportToWordCommandName, RadGrid.ExportToCsvCommandName
strReportTitle = ReportTitle.Trim
End Select
End Sub
Public Sub BindRadGrid1()
Dim strReportTitle As String
Dim dt As DataTable = Nothing
ReportTitle = dt.Rows(0).Item("ReportTitle")
strReportTitle = dt.Rows(0).Item("ReportTitle").ToString
'RadGrid1 Data source gets set here along with other stuff
End Sub
End Class
Using view state is normal, and Telerik controls need it to preserve their values across post-backs. A public string property on your page class should not persist, and should be set/calculated every time. If you absolutely need something like that to persist, save the value in a hidden server control, or have it in the QueryString of the URL.
So it turns out, that that variable was not truly persisting. It was getting its value from the bindradgrid1. When EnableViewState=True the need data source event is not fired, therefore the bindradgrid1 is not called and the variable does not get a value. Simple fix was adding a bindradgrid1() in the item command sub so that even with EnableViewState=True, bindradgrid1() will still get called. Thanks for all who helped.
I have to Get and Set the BackColur of Current Page. So user can use this property from any other page
And this is my code
Private _BackgroundColour As System.Drawing.Color
Public Property MenuBackColour() As System.Drawing.Color
Get
Return _BackgroundColour
End Get
Set(ByVal value As System.Drawing.Color)
_BackgroundColour = value
End Set
End Property
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
Try
NavigationMenu.BackColor = MenuBackColour
Catch ex As Exception
End Try
End Sub
But the problem is Property value gets cleared on PostBack so I'm not able to get the BackColor value from other page
On post back only the input elements are posted.
So they are the same as before the post back, what they have before the post back, have and now. So actually you do not "get" this parameters on code behind, you only "set" them and on server controls with viewstate on, you can remember this parametres on post back - but you can not change them on client side and expect to read this change on server.
Here the workaround is. Either use the viewstate of the page to save some values and keep them on post back, ether use input hidden elements to have them on post back.
If your main purpose is to retain or share the backcolor of some control between different pages, there are many ways to do it in ASP.NET. You can keep the value in cookies or sessions, or cache.
As per request, if Property must be used, I create a Default.aspx as the following:
Public Class _Default
Inherits Page
Private Shared _BackgroundColour As System.Drawing.Color = Drawing.Color.Azure
Public Shared Property MenuBackColour() As System.Drawing.Color
Get
Return _BackgroundColour
End Get
Set(ByVal value As System.Drawing.Color)
_BackgroundColour = value
End Set
End Property
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
MenuBackColour = Drawing.Color.Red
Response.Redirect("Default1")
End Sub
End Class
It will automatically be redirected to Default1.aspx, where there is a Label control in that page. It will use _Default.MenuBackColour as the label's backcolor:
Public Class Default1
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Label1.BackColor = _Default.MenuBackColour
End Sub
End Class
Again, this approach is not recommended. If Default.aspx has never been run (at least once), MenuBackColour's value may not be what you think it is. I won't encourage people to retain any static variable or property in an .aspx page for sharing.
In web applications, variable values simply get erased. But it is very simple to persist these values. They may be persisted using the Viewstate object. Before the postback is invoked, the variable's value is saved in a viewstate object. In the recieving page, the viewstate's value may be retrieved back.
//Save the value in ViewState object before PostBack
ViewState("myColour")="Black";
//Retrive the value from ViewState after the PostBack
myColourProperty=ViewState("myColour").ToString();
I have a server control that I am trying to get to save properties as control states but for some reason the properties are not persisting across partial postbacks.
The psuedo code is as follows:
Public Class FileUpload
Inherits ScriptControl
Implements INamingContainer, IPostBackEventHandler
Public Property newFileExt() As String
Get
Dim foundList As String = DirectCast(ViewState(Me.UniqueID & "_fileExt"), String)
If foundList IsNot Nothing Then
Return foundList
Else
Return String.Empty
End If
End Get
Set(ByVal value As String)
ViewState(Me.UniqueID & "_fileExt") = value
End Set
End Property
Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
MyBase.OnInit(e)
Page.RegisterRequiresControlState(Me)
End Sub
Protected Overrides Function SaveControlState() As Object
Dim controlState(6) As Object
controlState(0) = MyBase.SaveControlState()
controlState(1) = newFileExt
Return controlState
End Function
Protected Overrides Sub LoadControlState(ByVal savedState As Object)
Dim controlState() As Object
controlState = CType(savedState, Object)
MyBase.LoadControlState(controlState(0))
newFileExt = CType(controlState(1), String)
End Sub
end class
On this control is an asyncFileUpload ajaxcontroltoolkit control and a button. I have an event for upload complete:
Protected Sub SaveUploadedFile(ByVal sender As Object, ByVal e As AjaxControlToolkit.AsyncFileUploadEventArgs) Handles asyncFileUpload.UploadedComplete
newFileExt= "Some Value"
end sub
Protected Sub bntSelectResults_click(ByVal sender As Object, ByVal e As EventArgs) Handles bntSelectResults.Click
If (newFileExt= "") Then
'this always returns as empty
End If
end sub
So, UploadedComplete is complete it should set the controls state. then, when the user click the button it should read it. Through debugging, I can see that it is set correctly in UploadedComplete event but null when read. Is this due to the cycle of the page or something?
Thanks
jason
EDIT
I traced out the path for how the page cycle is running:
User clicks the async file upload control's browse button and selects a file. This causes the upload process to start
a. OnInit gets called
b. LoadControlState gets called
c. OnLoad gets called
d. asyncFileUpload.UploadedComplete gets called and I set the newFileExt property
here.
e. SaveControlState gets called. newFileExt is set here properly
User clicks a button on the control that initiates another partial postback/update of the update panel
a. OnInit gets called
b. LoadControlState gets called. I can see that the newFileExt property is not set
c. OnLoad gets called
d. Buttons click event gets called and the property is read (which is no longer set)
e. SaveControlState gets called and cycle ends
So, as best as I can tell, the asyncFileUpload application has issues with ViewStates/ControlStates. I ended up just just using sessions.
Partial Class ClientCenter_UpdateSub
Inherits System.Web.UI.Page
Structure PInfo
Dim Name As String
Dim Surname As String
End Structure
Dim OldPInfo As New PInfo
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
'blah blah
OldPInfo.Name = Dt.Rows(0).Item("Name").ToString
OldPInfo.Surname = Dt.Rows(0).Item("Surname").ToString
end if
end sub
End Class
The first time the page loads my structrure is filled correctly.
After an AJAX postback all the structure fields are setting to nothing. (It seems that the Dim OldPInfo As New PInfo is called again), but i should better ask the SO Experts.
So anyway, what am i doing wrong here?
First off, You should never assign a variable outside of a property or a method.
Second, web applications are stateless (which means NOTHING is automatically saved from call to call - unless you store it somewhere like Viewstate, Session, etc.).
Remember to accept this answer if it helps solve your problem.
I created a single page (with code behind .vb) and created Public intFileID As Integer
in the Page load I check for the querystring and assign it if available or set intFileID = 0.
Public intFileID As Integer = 0
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
If Not Request.QueryString("fileid") Is Nothing Then
intFileID = CInt(Request.QueryString("fileid"))
End If
If intFileID > 0 Then
GetFile(intFileID)
End If
End If
End Sub
Private Sub GetFile()
'uses intFileID to retrieve the specific record from database and set's the various textbox.text
End Sub
There is a click event for the Submit button that inserts or updates a record based on the value of the intFileID variable. I need to be able to persist that value on postback for it all to work.
The page simply inserts or updates a record in a SQL database. I'm not using a gridview,formview,detailsview, or any other rad type object which persists the key value by itself and I don't want to use any of them.
How can I persist the value set in intFileID without creating something in the HTML which could possibly be changed.
[EDIT] Changed Page_Load to use ViewState to persist the intFileID value
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
If Not Request.QueryString("fileid") Is Nothing Then
intFileID = CInt(Request.QueryString("fileid"))
End If
If intFileID > 0 Then
GetFile(intFileID)
End If
ViewState("intFileID") = intFileID
Else
intFileID = ViewState("intFileID")
End If
End Sub
As others have pointed out, you can store it in the Session or the ViewState. If it's page specific, I like to store it in the ViewState as opposed to the Session, but I don't know if one method is generally preferred over the other.
In VB, you would store an item in the ViewState like:
ViewState(key) = value
And retrieve it like:
value = ViewState(key)
Store in:
Session
ViewState
Hidden input
Just to summarize what is said above.
You can use Session, Viewstate, or a hidden field.
I personally prefer viewstate as it will work in web farm environments, Session does not, it does not store it on the server waiting for the user, for up to 20 minutes to be removed, and in general viewstate is the place to be for page level data.
You can use a hidden field, but then a user could more easily modify it.
Store it in the Session.
Page.Session["MyPage_FileID"] = intFileID
You'll need to have logic that manages it as the user navigates around, but if it is always set when the page loads from a GET (or you clear it, if not available on GET) then you should be ok using it later from the Session on your submit PostBack.
Remember:
Each time your server code runs, it's in a brand new instance of your page class. That's for every postback.
Actually, since an ASP.NET page postbacks to itself - including the query string - you could just remove the If Not Page.IsPostBack condition. Then it'd set itself on each postback.
I personally would choose to store the value in control state instead of viewstate as viewstate can easily be switched off. ControlState will persist even if viewstate is switched off for any reason. I have included an example on how this may be done.
Private intFileId As Integer = 0
Public Property FileID() As Integer
Get
Return intFileId
End Get
Set(ByVal value As Integer)
intFileId = value
End Set
End Property
Protected Overrides Function SaveControlState() As Object
Dim objState(2) As Object
objState(0) = MyBase.SaveControlState()
objState(1) = Me.FileID
Return objState
End Function
Protected Overrides Sub LoadControlState(ByVal savedState As Object)
Dim objState() As Object
objState = savedState
MyBase.LoadControlState(objState(0))
Me.FileID = CInt(objState(1))
End Sub
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
Me.Page.RegisterRequiresControlState(Me)
End Sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
If Not String.IsNullOrEmpty(Request.QueryString("fileid")) Then
Me.FileID = CInt(Request.QueryString("fileid"))
End If
End If
Response.Write(Me.FileID.ToString())
End Sub
Session["KeyName"] = your value;
Type cast to the type to retrieve and store the data from session like given below :
Datatable dt = (DataTable)(Session["KeyName"]);
or
ViewState["KEY"]= value;
Type cast to the type to retrieve and store the data from session like given below :
String str = (String)ViewState["KEY"];
I'll use Session as suggested by tvanfosson.
ViewState and HiddenField might be too heavy if you want to keep large data like a dataset for comments in a forum's topic pages..