Odd Visual Studio Checking Variable Value - asp.net

Really weird... So I'm trying to save the page index of my gridview in a Session Variable and then reset the index when the user navigates back to the gridView. Here's my code below;
Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As EventArgs)
If Not Page.IsPostBack Then
If Not Session("CurrentPage") Is Nothing AndAlso
Session("CurrentPage") <= GridView1.PageCount Then
GridView1.PageIndex = Session("CurrentPage")
End If
End If
End Sub
Well the weird thing is that when I breakpoint on the second IF above and hover over pageCount it says it's 0. If I then go into my watch window and look at it (0 once again), then go back to my code and hover again it's 2 (which it should be)! I can then Continue past the break point and the page displays on page 2 as it should. However, and this is where it gets really weird, if I remove the breakpoint and run it I end up on page 1! So it's as if the PageCount hasn't updated unless I've put a breakpoint on it and specifically looked at it. Anyone explain this behaviour and how to get around it?!
UPDATE
Here's a pic of the values of the variables in question. You can see the PageIndex wasn't updated because it never entered the IF statement because moments earlier the PageCount was 0!! I can't be the only one stumped by this :/
Image of variable values:

I guess you may need to cast your Session value to Integer
If Not Session("CurrentPage") Is Nothing AndAlso
DirectCast(Session("CurrentPage"),
Integer) <= GridView1.PageCount Then
GridView1.PageIndex = DirectCast(Session("CurrentPage"),Integer)
End If

Ok bit hacky but it works. Simply used;
If Not Session("CurrentPage") Is Nothing Then
GridView1.PageIndex = DirectCast(Session("CurrentPage"), Integer)
End If
Couldn't get the GridView.PageCount to equal 2 except by going into the WatchWindow and refresh the value field (would be hard to explain to your everyday online user how to do that so that wasn't really an option :P ). So I tried just leaving it out. Works fine now. Could possibly run into a page does not exist error but I imagine it would be quite unlikely as the number of pages doesn't change much at all and Session("CurrecntPage") variable is updated quite regularly.

Related

dropdownlist selectedvalue doesnt change

I have this dropdownlist, this one load with the data that I get from a store procedure, as you can see the load is correct, but when I change the selected value in the debug the selected value doesnt change, it stays in the first loaded value, which in this case is 1. What can I do?
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim adaptador As New SqlDataAdapter
Dim datos As New DataTable
Dim ord As SqlDataReader
Conexiones.AbrirConexion()
Conexiones.Cnn.Open()
Dim cmd As SqlCommand = New SqlCommand("sp_devolver_empresas", Conexiones.Cnn)
cmd.CommandType = CommandType.StoredProcedure
ord = cmd.ExecuteReader
datos.Load(ord)
cbEmpresas.DataSource = datos
cbEmpresas.DataTextField = "Nombre"
cbEmpresas.DataValueField = "Identificador"
cbEmpresas.DataBind()
Conexiones.Cnn.Close()
End Sub
For EVERY web page that you build and write to the end of time?
You MUST always put the load and setup code inside of a check for post back.
every button, every drop down list, and EVERY time you click on a button or do anything, the page load will ALWAYS fire and run. Thus if you change a value, you will lose that value since the page setup and loading of say control (in this case your dropdown list) will fire EACH time - thus overwriteing.
Out of the last 100's of web pages, the FIRST thing I write is the check for postback.
So, your code should look like this:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
LoadData
End If
End Sub
Sub LoadData()
Dim datos = New DataTable
Using onexiones.Cnn
Using cmd As SqlCommand = New SqlCommand("sp_devolver_empresas", onexiones.Cnn)
cmd.CommandType = CommandType.StoredProcedure
onexiones.Cnn.Open()
datos.Load(cmd.ExecuteReader())
End Using
End Using
cbEmpresas.DataTextField = "Nombre"
cbEmpresas.DataValueField = "Identificador"
cbEmpresas.DataSource = datos
cbEmpresas.DataBind()
End Sub
So, only on the "real" first page load do you want to load up your grids, dropdowns etc. Remember, even a simple button dropped on to the page, and you have a click event? (the page load event fires each time - and every time). So once again, you need the IsPostBack test - and I am quite pressed to find any of my web pages that does not have this all important code stub in the on-load event.
So, remember the above rule - always setup your setup code to run on first time - not every time a button or anything else occurs on the web page. So, page load (unlike desktop) fires each and every time you do ANY operations on that page.
Also, note how I setup the data text, and value field BEFORE we give the drop down list a data source. In fact, I would suggest you put the data text, and data value field in the markup and NOT code (since then multiple different code routines can use that setting - not hard coded in code).
eg do this:
<asp:DropDownList ID="cbEmpresas" runat="server"
DataTextField = "Nombre"
DataValueField = "Identificador" >
</asp:DropDownList>
So, now your code becomes :
cbEmpresas.DataSource = datos
cbEmpresas.DataBind()
I suppsoe some out of habt like to set the text + data settings for the dropdown list in code, but then again, in code you might want more then one palce that loads up the combo box - and thus you now have multiple places for those two settings. And better yet, you can even use the property sheet during design time to make the settings. (this is a "minor" issue, but I just perfer those settings in the markup as opposed to writing them in code for text/data settings).
At the end of the day? Just remember that golden rule: have that "test" for postback so you have a REAL first page load event code inside that if/then. In fact, you really can't even build a fnctional working web page if you break this rule. As noted, I count about 1-2 of my web pages out of 100's tht don't have that not postback code stub. It is quite much as important say compared to humans having to breathe air to function.
And why such a long post about this simple issue? Well on a near daily bases, both c# and vb.net questions are posted about how some combo box, grid view or just about anything else is "broken" and not working. And the answer 9 out of 10 times?
The developer forgot to use a Not IsPostBack code stub in their page load code.
If I was teaching asp.net, this would be the first lesson - ALWAYS use and consider the requirement for the Not IsPost back stub. You need that in 99% of your web pages. Or at the very least in ANY web page in which you have code to run on page load to setup grids, dropdowns, repeaters - don't matter what, you will NEED that code stub. So important, I often wonder if they should have create a even called first page load? It would have eliminated the daily posts and questions on SO that fail as a result of not heeding the above simple advice.
Edit: Now how to get selected value in code
Ok, now that we fixed up the code to setup the dropdown list, we now want to get in our code the value when the user makes a choice in the dropdown list.
You of course have code to fill the dropdown, BUT we also have to set autopostback = true for this dropdown.
So, say code to load:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
LoadData
End If
End Sub
Sub LoadData()
Using conn As New SqlConnection(My.Settings.TEST4)
Dim strSQL As String =
"SELECT ID, HotelName from tblHotels ORDER BY HotelName"
Using cmdSQL As SqlCommand = New SqlCommand(strSQL, conn)
conn.Open()
Dim rstData As New DataTable
rstData.Load(cmdSQL.ExecuteReader)
cboHotels.DataSource = rstData
cboHotels.DataBind()
End Using
End Using
End Sub
And now the selected index changed event:
so, our debug output would then look like:
output:
combo selected value = 82
combo selected Text = Canadian Rocky Mountain Resorts
And as noted, make sure you set auto-post back true in the property sheet, or in the markup. The combo box for above in markup thus is this:
<asp:DropDownList ID="cboHotels" runat="server"
DataValueField="ID"
DataTextField="HotelName" AutoPostBack="True">
</asp:DropDownList>

Label is not visible . I need to show a message please wait when the user clicks login

Label is not visible in the following code . I need to show a message please wait when the user clicks login.It shows before but after adding the time interval its not showing
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Label3.Visible = True
If TextBox1.Text = "Akilan" And TextBox2.Text = "123" Then
System.Threading.Thread.Sleep(5000)
Form2.Show()
Hide()
Else
MsgBox("Sorry, The Username or Password was incorrect.", MsgBoxStyle.Critical, "Information")
End If
End Sub
Thread.Sleep on the UI thread will cause your form to "freeze". It sounds like you want some sort of waiting indicator while the background code is running.
What you should do is execute your long running code asynchronously, show your label, wait for the asynchronous code to finish, then do something (e.g. hide the label).
Using your code, it'd look something like this:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Label3.Show()
If (TextBox1.Text = "Akilan" AndAlso TextBox2.Text = "123") Then
Dim t = Task.Run(Sub() Threading.Thread.Sleep(5000))
t.Wait()
Label3.Hide()
Else
MessageBox.Show("Sorry, the username or password was incorrect", "Invalid Credentials", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
End Sub
The way to do this is to hide/show the label text client side. Then when the page travels up to server and your code behind runs, the client side will still show that message. When you code behind is done, then the whole page now travels back down to the client side is re-load + re-display.
Grasping the above so called "round trip" is REALLY important here.
Since your code behind never interacts with the user, but only that copy of the web page that JUST traveled up to the server, and the code behind can play with, change and modif that page - but client side can ONLY see such updates AFTER the page travels all the way back down to client side. That's why this code can't work:
Label3.Visible = True
If TextBox1.Text = "Akilan" And TextBox2.Text = "123" Then
System.Threading.Thread.Sleep(5000)
Form2.Show()
Hide()
The above code will set Label.visible = true, but the whole page has not yet done its code, and the whole page is still on the server side. ONLY AFTER all your code is done, does the page travel back to client side, and show the label - but ALL code has to complete before page travels back down to client side.
However, this code will work just fine:
So lets look at above:
First up, we do NOT use visible=false for the label. The reason is that if you do that, then the label is NOT rendering in the markup.
Next up, we added a onclient click event to the button.
And we have our button code that has this code:
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Thread.Sleep(3000)
End Sub
So, when you run this, you see this for 3 seconds:
So what happens?
Well, you click on button - the OnClient code (javascrt client side) will run and THEN the post back of the page up to the server occurs.
So, since that label is now "show", then it will display. Now the web page is up on the server - your code behind runs. When code behind is done?
The WHOLE page now makes the trip back to browser client side. And this ALSO means our label message will automatic hide again - since the page is re-plotted with the whole new page that the server just send back to the client side.
Do note, that in above, I assumed jQuery is installed. If not then your script will have to be this:
function ShowLabel()
{
lbl = document.getElementById("lblMessage")
lbl.style.display = "inline"
}
Note also close how I set the id mode of lable = static - I often do that, since then referencing controls in js becomes a lot easier.
So, the real trick here?
We display the label client side, and then whatever and how ever long the server takes is the amount of time the label will display. And when that whole new fresh web page comes back down from the server, then the label will re-vert back to being hidden (display:none).
So, do keep in mind this VERY important concept of round trip. When you code runs behind and changes values or controls on the page? The end user does NOT see such changes until ALL code behind is done, AND THEN the page travels back down to the user. In fact, then your code behind to hide or show, can become before or after the delay in code - it will NOT update client side and in fact the order that that change label and delay will NOT matter (since the web page is STILL up on the server). So all your changes you make to the page remain up on the server until all code is done, and THEN the whole page comes back to client side to show such changes.
The other way would be to consider ajax calls - but baby steps here first, right?
You can make Button Click event asynchronous.
The following code works for me:
Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Label3.Visible = True
If TextBox1.Text = "Akilan" And TextBox2.Text = "123" Then
Label3.Text = "Please wait"
Await Task.Delay(500)
Label3.Text = ""
Form2.Show()
Hide()
Else
MsgBox("Sorry, The Username or Password was incorrect.", MsgBoxStyle.Critical, "Information")
End If
End Sub
Also check:
Async (Visual Basic)
When to use Task.Delay, when to use Thread.Sleep?

ASP.NET Details View - Editing into Null Value Error

I am using ASP.NET in Visual Studio 2010.
I have a website that features a shopping cart, the user can signup which has validation using the RequiredFieldValidator control meaning they must enter something for certain fields e.g. Address 1 / E-Mail. This is also tied to a Database which for these fields does not allow null values.
My issue that is after logging in, adding items to cart, quantities etc, I have a confirmation order page - similar to most online shopping websites were the shopping basket is displayed along with the user's Customer Details, which is shown through a DetailsView, connected to a SqlDataSource which is running a query that just displays their shipping details as previously entered.
However, if I say select Edit, which is using the DetailsView's own property and change the Address1 line to nothing, the DetailsView sends it as null value after accepting and as a result the whole thing crashes.
I have tried examples like:
Protected Sub DetailsView1_PageIndexChanging(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DetailsViewPageEventArgs) Handles DetailsView1.PageIndexChanging
Try
Catch ex As Exception
lblError.Text = "Please verify changes made to Customer Details."
End Try
End Sub
Protected Sub DetailsView1_ItemUpdating(ByVal sender As Object, ByVal e As DetailsViewUpdateEventArgs) Handles DetailsView1.ItemUpdating
Try
Catch ex As Exception
lblError.Text = "Please verify changes made to Customer Details."
End Try
End Sub
Protected Sub detailsView1_ItemUpdated(ByVal sender As Object, ByVal e As DetailsViewUpdateEventArgs) Handles DetailsView1.ItemUpdating
Try
Catch ex As Exception
lblError.Text = "Please verify changes made to Customer Details."
End Try
End Sub
So basically Try / Catch statements which has worked for everything else. But because I can't get access to any proper code behind for the DetailsView since it's just taken from Visual Studio I'm stumped. Has left me curious now, looked about here and elsewhere and couldn't find much, anything seemed similar to what I've tried there but they don't make a difference.
I want to try and create/find some form of Error Handling for this situation, similar to registering, either not proceeding with sending to the server if left blank or display a message.
This is the main part of the error:
[SqlException (0x80131904): Cannot insert the value NULL into column 'Address1', table 'C:\USERS\xxxx\PROJ (2)\PROJ\APP_DATA\ORDERS.MDF.dbo.Customer'; column does not allow nulls. UPDATE fails.
The statement has been terminated.]
Something simple I'm missing? Was considering the option of creating text boxes instead and connecting to the database individually, but that's a completely different route to this and there is quite nice, simple customizable options with the DetailsView.
Well...typical after spending weeks confused by this one I managed to get it just after posting the question.
For anyone interested in this I used the 'If e.Exception Is Nothing Then' statement within the code similar to the two bottom examples I tried, THEN, used a Try/Catch statement.

IIF statement to determine visibility of ImageButton in GridView not evaluating properly

I have a GridView that displays user info along with two template fields with imagebuttons. One is to open up a detailsview to edit user information. The other is to edit the user's password.
In my Code Behind, I have 3 IIf statements that check for certain criteria. Based on certain combinations of this criteria, I want the ImageButtons to either show/not show appropriately.
Here is my code behind:
Protected Sub gvUsers_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles gvUsers.RowDataBound
Dim isProvisioned As Boolean
Dim acceptedToS As Boolean
Dim isSuspended As Boolean
'hide password change option for users that have not yet been provisioned or have not accepted ToS Agreement or have been suspended'
If e.Row.RowType = DataControlRowType.DataRow And _
DirectCast(sender, GridView).EditIndex <> e.Row.DataItemIndex Then
isProvisioned = IIf(String.IsNullOrEmpty(e.Row.DataItem(GUser.columns.DATEADDED).ToString), False, True)
acceptedToS = IIf(String.IsNullOrEmpty(e.Row.DataItem(GUser.columns.TOSTIMESTAMP).ToString), False, True)
isSuspended = IIf(String.IsNullOrEmpty(e.Row.DataItem(GUser.columns.SUSPENDDATE).ToString), False, True)
Dim btnAdminEdit As ImageButton = DirectCast(e.Row.FindControl("btnAdminEdit"), ImageButton)
Dim btnAdminSelect As ImageButton = DirectCast(e.Row.FindControl("btnAdminSelect"), ImageButton)
btnAdminEdit.Visible = Not (isSuspended) AndAlso isProvisioned AndAlso acceptedToS
btnAdminSelect.Visible = isProvisioned
Else
gvUsers.EmptyDataText = "No records found matching specified criteria."
End If
End Sub
I don't know what changed because this code DID work at one point. However, when I test the page, both imagebuttons seem to show up no matter what. While debugging, I also saw that it seemed to "evaluate" each row the same way. As in, for each row that went through my IIf statements, it always returned the same values, even if it was not true.
I have a hunch that it's taking the first row's values and reusing it some how, or evaluating the same row; that's why it always returns the same values and always shows the imagebuttons, even though they are not supposed to be visible according to my IIf statements.
Any help is greatly appreciated as I'm not too sure how to resolve it from here.
Well, after delving a little deeper, I found what was causing the problem.
The last change I made before seeing this problem was the addition of another column to be displayed in the GridView. This distorted the index of the columns so my IIF statements were not checking the correct datafields and thus, were evaluating incorrectly.
So, the code behind I posted does work and luckily proved that I wasn't going crazy. The logic is correct!
Thanks to those who took time to glance at this question!

DevExpress - Xtra Reports: VB.NET How to get current page number?

I've searched their site. I just want to find the page number in the vb script. I have a report header, and if it is on page #1 then I want a page break after.
This code should do the trick. It's the PrintOnPage event handler for a label in your Report Header.
Private Sub xrLabel1_PrintOnPage(ByVal sender As Object, ByVal e As DevExpress.XtraReports.UI.PrintOnPageEventArgs) Handles xrLabel1.PrintOnPage
If e.PageIndex > 0 Then
ReportHeader.PageBreak = DevExpress.XtraReports.UI.PageBreak.None
Else
ReportHeader.PageBreak = DevExpress.XtraReports.UI.PageBreak.AfterBand
End If
End Sub
Note that the PageIndex value is zero-indexed. Also, the page index is only available (as far as I know) in the PrintOnPageEventArgs, so this won't work in a Before/AfterPrint event.
See this knowledge base article for reference.

Resources