|
The newsletter is compiled by DevCity.NET NewsMasters Ged Mead and Mike McIntyre
AdvertisementTable Of Content:
Advertisement
.netCHARTING - Image Is Essential
The best looking ASP.NET charts can now save you even more time with automated multi-chart drilldown, enhanced data integration, and a new template system. Version 2.1 continues to push the envelope for dynamic web based charting with 4 stunning new visual effects, two for bars / columns and two for bubbles. Download your free developer version today!
We at DevCity.NET, use .netCHARTING - give it a try too: http://www.dotnetcharting.com
by Ged Mead
Have you ever had one of those "Eureka!" moments while you were programming?
Of course you have!
Otherwise I'm sure you would have given up programming long ago and got yourself a more rewarding, satisfying and fulfilling job.
Public Toilet attendant, perhaps. Or Keeper of the Royal Underpants. Or Duty Boil Squeezer at County General . But I digress.....
I was fiddling about trying to knock out a very simple Windows Form on which the user could drag controls at run time and place any of them on top of a large PictureBox.
Now, I know you're probably sat there thinking that that's a pretty easy call.
And I agree.
Mouse Down on the label, drag to chosen new location, release mouse, job done.
Change the values of the Left and Top Properties of the control you want to move and it will move there. Use the relative position of the mouse from the mouse's start point to the point where the user releases the mouse to calculate how far to move .
Doesn't need an MSc in Computing to work that one out. But, strangely, the results I was getting weren't really very satisfactory.
And that's putting it kindly. Actually, it was a total shambles.
If I put this code in the MouseMove event:
Label.Left = e.X
Label.Top = e.Y
I found myself chasing the label round the form until I finally trapped it in the corner. Then when I tried to drag it away, it began to create very shaky, flaky clones of itself.
My thinking at this point was that if I moved the top left corner of the label control to the location of the cursor then any movement of the mouse cursor would be reflected by a corresponding movement of the label. But, nope, that definitely didn't work.
Hmmmm, Plan B then. Swiftly followed by Plans, C, D and E. Most of them created variations of the mysterious "Case of the Disappearing Label"; apparently one of the very few cases that Perry Mason failed to crack.
OK, the Eureka moment. Actually "moments", plural. Searching around for code samples that actually worked (as opposed to my rather sad demos of how not to do it) I came to realise several things.
The first key thing I hadn't understood was that e.X and e.Y were both relative to the control (That is, the Labels and small PictureBox controls I wanted to move). I really don't know why, but for some reason I was under the impression that those X and Y values were related to the Form.
No wonder the attempts had all failed.
Secondly, I realised that it was no good just moving the control whenever the MouseMove event of the control was fired. The control would move even if the cursor was being passed over it with no button being held down. I only wanted the label to move if the Mouse had first been pressed down on the control. So the addition of a Boolean variable to keep track of this was the next step:
Dim Dragging As Boolean
And when the mouse is pressed down on one of the controls that we want to move, the Boolean flag is set to True.
That done, in the MouseMove event we can test to see if the user wants us to move the control:
If Dragging Then
and if it is, we go ahead and move it. To do this, I needed to track where the user was dragging the mouse to and use that movement to move the control. Crucially, I also had to make proper use of that offset value that we had taken a note of earlier, i.e. when the user first clicked on the control. This would make the cursor stay in the same relative position on the control while the control was being moved, but also that the control would now move as the mouse cursor moved.
Having finally got all that clear in my head, it was relatively easy to put together a set of procedures which could handle all of the movable controls - namely lblAccept,, lblReject and the PictureBox, PBSmall :-
Dim cursorX, CursorY As Integer
Dim Dragging As Boolean
Private Sub Control_MouseDown(ByVal sender As System.Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles lblAccept.MouseDown, lblReject.MouseDown, PBSmall.MouseDown
' Set the flag
Dragging = True
' Note positions of cursor when pressed
cursorX = e.X
CursorY = e.Y
End Sub
Private Sub Control_MouseUp(ByVal sender As System.Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles lblAccept.MouseUp, lblReject.MouseUp, PBSmall.MouseUp
' Reset the flag
Dragging = False
End Sub
Private Sub Control_MouseMove(ByVal sender As System.Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles lblAccept.MouseMove, lblReject.MouseMove, PBSmall.MouseMove
If Dragging Then
Dim ctrl As Control = CType(sender, Control)
' Move the control according to mouse movement
ctrl.Left = (ctrl.Left + e.X) - cursorX
ctrl.Top = (ctrl.Top + e.Y) - CursorY
' Ensure moved control stays on top of anything it is
' dragged on to
ctrl.BringToFront()
End If
End Sub
And then it was time for my bath... On reflection, maybe I should have mulled the problem over in the bath first and saved a lot of time and quite a bit of aggravation. Well, it worked for Archimedes!
Programming, huh? Sometimes it's all Greek to me.
- Junior (Ged Mead aka XTab, xtab@vbcity.com)
AfterNote: Having had reason to post up the code in answer to a question while this article was going to print, I can also point you to another approach suggested by Mark Dryden. You can read the Topic here.
by Ged Mead
Following my Diary item in the last issue, two newsletter readers - Tinco Andringa and Steve Gravitz - took the time to mail me with a suggestion to ease the problem of those pesky single and double quote combos.
Both of them reminded me that the String.Format method is available in these situations.
So we can apply this method to the examples in that DataView Filtering example in the article:
DataView.Rowfilter = [string].Format("LastName Like " & _
"'{0}%'",CStr(lstLetters.SelectedItem))
and
dvAddresses.RowFilter = String.Format("{0} Like '%{1}%'", _
ColToCheck, txtSearchPhrase.Text)
Although it doesn't entirely overcome the fiddly syntax needed for the task, it certainly does compartmentalise the code and so makes it easier to decipher.
... and talking of making spaghetti code easier to decipher, Steve also showed me an example where a very unwieldy SQL statement could be tamed with the help of the String Format method. Notice how in this example, the proliferation of single, double and no quotes are neatly handled.
Sq.AppendFormat("{0} = dbo.{1}('{2}', {3}, '{4}', '{5}'), {6}", _
"WEBHITS", _
"dta_TotalsForCell", _
m_CellMatrix_ID, _
"Cell_ID", _
"RESPONSES_WEBHITS", _
"@@LAST_RESPONSE_DATE@@", _
vbCrLf)
Thanks to Tinco and Steve for bringing out these suggestions.
- Junior (Ged Mead aka XTab, xtab@vbcity.com)
by Mike McIntyre
Part 1 of 3
This article discusses the ASP.NET 'Session ID Cookie', 'State Cookie', and 'Cookieless Session' state management options which are part of the bigger picture of caching mechanisms in ASP.NET. The diagram below expresses the context of this article.
.NET Framework
ASP.NET
Caching
Session State
Session ID Cookie
State Cookie
Cookieless Session
Session ID Cookies, State Cookies, and Cookieless Session are important caching mechanisms. Choosing which state management option to use in an ASP.NET web application, either cookies or cookieless session, impacts application design, security, performance, scalability, user experience, accessibility, code review, and deployment.
Caching
ASP.NET state caching is a key technology for optimizing an application's security, performance, scalability, and availability. State ID Cookie, State Cookie, and Cookieless Session are important components of the ASP.NET state caching technology.
State
State refers to data, and the status or condition of that data, being used within a system at a certain point in time. That data may be permanently stored in a database, may be held in memory for a short time while a user executes a certain function, may be cached in memory, cached in a SQL database, cached in a session service, or cached to a client computers hard drive.
Session State
ASP.NET session state provides a way to persist a piece of information about a client for the duration of time the user interacts with an ASP.NET web forms application.
By default, session state is maintained in memory in the same process and AppDomain as an ASP.NET web application.
Session state is accessible through the Session property of both the ASP.NET Page and HttpContext classes. When a request comes in to an application, the Session properties of the Page and HttpContext class used to service that request are initialized to the current instance of HttpSessionState that is associated with that particular client.
Session state for specific client is assigned a unique session ID.
Associating Session State Client Requests
To associate session state stored on a host with a client request, it is necessary to identify an incoming request as having been issued by a given client.
A session's ID is used to associate a client's request with a client's session state on the server.
The first time a client connects to an ASP.NET site an ASP.NET Session object is instantiated to hold the client's session data.
ASP.NET generates an encrypted alphanumeric session ID, assigns it to the Session object, and passes the session ID to the client in the response. Session ID can be passed to the client in a cookie or the mangled URL, as explained later in this article.
In subsequent requests the client passes the session ID back to the server.
When the server receives a request that includes a session ID it associates an ASP.NET session object with the client's request. It processes the page and then returns a response that includes the session ID back to the client. This back and forth passing of the session ID in requests and responses goes on until the session is terminated.
IMPORTANT: An ASP.NET web forms application must be configured to use cookies OR cookieless session to associate session state with client requests. It is not possible to specify that an application should use cookies if the client supports cookies and cookieless session if the client does not support cookies.
Session ID Cookie
A Session ID Cookie is the default mechanism for associating a client's session state on the host across multiple requests made by the client. With this mechanism, a session ID cookie is created by the host and stored in a client's web browser memory. A session ID cookie is erased when the client terminates the session.
Clients who have disabled cookies in their browser CAN NOT use an ASP.NET application that uses a session ID cookie.
Some browsers DO NOT support cookies.
State Cookie
A State Cookie is a mechanism for caching state on a client's computer, either in browser memory or on the client computer's hard drive.
With state cookies, state other than session ID can be stored in cookie(s) in the client browser's memory or on the client's hard drive.
Transient State Cookie
A state cookie containing state other than session ID may be stored temporarily in a client's web browser memory. A state cookie stored in web browser memory is transient. It is erased when the client closes the web browser to terminate a session.
If the expiration date property of a cookie is not set, a cookie will be transient.
Client's who have disabled cookies in their browser CAN NOT use an ASP.NET application that uses transient state cookies.
Persistent State Cookie
A cookie containing state other than session ID may be stored permanently or for a period of time on a client's hard drive. A cookie stored on a client computer's hard drive is persistent. It is not erased when the client closes the web browser to terminate a session. A persistent cookie is stored on a client's hard drive until it expires OR until the user deletes the cookie.
If the expiration date property of a cookie is set, a cookie will be persisted on the client's hard drive.
Clients who have disabled cookies in their browser CAN NOT use an ASP.NET application that uses persistent state cookies.
Next Installment: Cookieless Sessions
by Fadzai Chamba
I was reminded of a rather curious issue with floating point numbers last night that I think most new programmers are not familiar with. You would assume that the reason we would use floating point numbers is for greater precision. They have an accuracy that integer types cannot handle. And here is where the point is missed; surprisingly, if you are not careful, you could be serving users with very inaccurate figures.
The floating Types
.NET has given us three floating point types to use and these are Single, Double and Decimal. Single gives us a 32-bit single precision floating point number, while Double is a 64-bit double precision number.
Values that are considered valid for a Single number range from -3.4028235E+38 to -1.401298E-45 for negative numbers and from 1.401298E-45 to 3.4028235E+38 for positive numbers. This is very precise. Valid values for a Double range from -1.79769313486231570E+308 to -4.94065645841246544E-324 for negative values and from 4.94065645841246544E-324 to 1.79769313486231570E+308 for positive values. This is very, very precise; indeed more than the average developer will need
The issues
One issue that might come as a shock to the novice developer is that the precision afforded by these types can cause inaccuracy problems. To illustrate my point, we are going to try to add 0.001 to a Single a thousand times. Of course we know that the result is 1, but stay with me for a moment. Run this code in a new Console application and see what happens.
Dim sng As Single = 0, int As Long
'string builder for report...
Dim sb As New System.Text.StringBuilder
'go through the list a thousand times adding .001
For int = 1 To 1000
sng += CSng(0.001)
Next
sb.Append("The value of 'sng' is: " & sng.ToString())
Console.WriteLine(sb.ToString())
As you will find, the result is 0.9999907. As I did, you may want to stop using Single for any mission-critical floating
I'll take a Double
Let us now run this code using a Double also and see what happens.
Dim sng As Single = 0, dbl As Double = 0, int As Long
Dim sb As New System.Text.StringBuilder
For int = 1 To 1000
sng += CSng(0.001)
dbl += 0.001
Next
sb.Append("The value of 'sng' is: " & sng.ToString())
sb.Append("\nThe value of 'dbl' is: " & dbl.ToString())
Console.WriteLine(sb.ToString().Replace("\n", Environment.NewLine))
As we have seen, Single is still inaccurate but Double gives us the value 1 as we expected. However, we should not perhaps be satisfied with one single successful experiment. Instead of going through 1000 times, go through the loop 10,000 times adding 0.0001 in place of 0.001. After running this code you will observe that both cases have some inaccuracies.
Some people might think that it is OK, we can always round off, and the values are close enough to the correct answers. But some users may not to round off those Double and Single precision numbers. It is also worth pointing out that Single has missed the mark by a greater magnitude of error.
Why this happens
Have a look at what the Microsoft Office XP Developer documentation has to say about floating point numbers:
The Single and Double data types are very precise - that is, they make it possible for you to specify extremely small or large numbers. However, these data types are not very accurate because they use floating-point mathematics. Floating-point mathematics has an inherent limitation in that it uses binary digits to represent decimals. Not all the numbers within the range available to the Single or Double data type can be represented exactly in binary form, so they are rounded. Also, some numbers cannot be represented exactly with any finite number of digits - pi, for example, or the decimal resulting from 1/3.
Because of these limitations to floating-point mathematics, you might encounter rounding errors when you perform operations on floating-point numbers. Compared to the size of the value you are working with, the rounding error will be very small. If you do not require absolute accuracy and can afford relatively small rounding errors, the floating-point data types are ideal for representing very small or very large values. On the other hand, if your values must be accurate - for example, if you are working with money values - you should consider one of the scaled integer data types.
What should I use then?
This is not really bad news if you can afford to have small rounding errors. However, if you want to have full accuracy you will have to leave Single and Double alone. The best choice is to use the Decimal type which is a fixed point data type.
Don't take my word for it; let us run the same litmus test on Decimal that we ran on the others.
Dim sng As Single = 0, dbl As Double = 0, dcm As Decimal = 0, int As Long
Dim sb As New System.Text.StringBuilder
For int = 1 To 10000000
sng += CSng(0.0000001)
dbl += 0.0000001
dcm += CDec(0.0000001)
Next
sb.Append("The value of 'sng' is: " & sng.ToString())
sb.Append("\nThe value of 'dbl' is: " & dbl.ToString())
sb.Append("\nThe value of 'dcm' is: " & dcm.ToString())
Console.WriteLine(sb.ToString().Replace("\n", Environment.NewLine))
The results are not so shocking in the wake of what we discovered about the other types.
- The value of 'sng' is: 1.064767
- The value of 'dbl' is: 0.99999999975017
- The value of 'dcm' is: 1.0000000
The Decimal data type
Decimal variables are stored as signed 128-bit (16-byte) integers scaled by a variable power of 10. The scaling factor specifies the number of digits to the right of the decimal point; it ranges from 0 through 28. With a scale of 0 (no decimal places), the largest possible value is +/-79,228,162,514,264,337,593,543,950,335. With 28 decimal places, the largest value is +/-7.9228162514264337593543950335, and the smallest nonzero value is +/-0.0000000000000000000000000001 (+/-1E-28).
The bottom line
The text in the 'Why This Happens' section refers to "one of the scaled integer data types". This was referring to the Currency and Decimal types in Classic VB. However, .NET doesn't support the Currency type, so in our case this refers to Decimal. This gives you the best guarantee of accuracy.
The bottom line is that if you are writing an application for automatic aircraft control, space ship guidance, or a world domination program, you will need much more accuracy than that offered by the Single and Double types and in .NET you will have to use the Decimal data type.
MultiThreading in .NET
VBCity Leader John Spano has written a very comprehensive and detailed article on this important topic. As he explains in his introduction:
"Multithreading, a very powerful technique, is essential for modern software development. Software users expect to work with a very responsive program that they don’t have to wait on, which is a very reasonable demand with the processor speeds that are currently available.Enter multithreading. Multithreading is the concept of having several different paths of code running at the same time."
To read the full article, click here.
http://www.devcity.net
Advertisement
Print Your .NET Source Code In Style!
PrettyCode.Print for .NET supports both VB.NET and C# solutions, it can be run standalone or as VS.NET Add-In. It prints WinForms source code as well as WebForms (ASP.NET) CodeBehind. Features Syntax Highlighting, AutoIndent, Watermarks, Export to PDF, Orphan Control, Line Bracket Connections for code blocks and much more
For your FREE evaluation copy visit PrettyCode.com
Finally, a Professional Source Code Printout - now in new .NET flavor!
by Newsletter Staff
Vote for vbCity!
Support vbCity in the .NET Developer's Journal 2004 Readers' Choice Awards Voting Ballot.
We've worked hard to make vbCity and DevCity.NET the best VB and .NET Community on the Net. Show your support by casting your vote in the .NET Developer's Journal Readers Choice Awards.
Click here to cast your vote for vbCity in the "Best .NET Web Sites" Section.
Thank you!
DevCity.NET Team
http://dndj.sys-con.com/general/readerschoice.htm
Advertisement
|