-
Aug 19th, 2013, 04:31 AM
#1
Thread Starter
Hyperactive Member
[RESOLVED] Call event handler sub
Hi Folks
I have an TextBox.KeyPress event handler sub that essentially does the following
VB Code:
Private Sub IdBox_KeyPress(sender As System.Object, e As System.Windows.Forms.KeyPressEventArgs) Handles IdBox.KeyPress ' Handle any "Enter"-key presses in the Id TextBox when the entered text length is greater than 0. If Asc(e.KeyChar) = Keys.Enter And IdBox.Text.Length > 0 Then Dim Id As String = IdBox.Text ' Indicate that the keypress is handled. e.Handled = True Try ' Create a new widget in the widget collection. widgets.Add(newWidgetKey, New Widget(IdBox.Text)) Catch ex As AlreadyInUseException ' Exception if ID is already in use. ' Ask the user if they would like to cancel the ID already in use . Dim userReply As DialogResult = MessageBox.Show("Could not use that ID as it is listed as being already in use." _ + vbNewLine + "Would you like to cancel the currentID?", _ "ID in use", MessageBoxButtons.YesNo, MessageBoxIcon.Error, _ MessageBoxDefaultButton.Button2) If userReply = Windows.Forms.DialogResult.Yes Then ' If the user wishes to cancel the ID, ' list the widgets with that ID from the collection of current widgets. Dim duplicateWidgets = (From widget In widgets Where widget.Value.Id = IdBox.Text Select widget.Key).ToList ' Check if the list has any items. If duplicateWidgets.Count > 0 Then ' Cancel each listed widget. For Each widgetKey As UInteger In duplicateWidgets widgets.Item(widgetKey).CancelWidget() widgets.Remove(widgetKey) Next End If Try ' Try creating the new widget in the widget collection again. widgets.Add(newWidgetKey, New Widget(IdBox.Text)) Catch exRe As Exception ' If there were still exceptions, make the user start again. MessageBox.Show("Still could not use that Id" + vbNewLine + _ exRe.Message, "Id could not be used", _ MessageBoxButtons.OK, MessageBoxIcon.Error) Exit Sub End Try Else ' If the user wishes to try another Id instead, ' Select the text in the Id box, ready for attempting a new Id. IdBox.SelectAll() Exit Sub End If Catch ex As Exception ' Exception if .Add() failed or New() failed for unknown reason - This should never happen. MessageBox.Show("Id validation failed for an unknown reason." + vbNewLine + _ "Please try again.","Id validation failed") IdBox.SelectAll() Exit Sub End Try End If End Sub
In plain English, the user enters and ID into the TextBox and presses the enter key, the event handler tries to create a widget with that ID, but will fail if there is already another one with the same ID.
The user then is presented with a choice, cancel the older widget and continue creating the new one, or try another ID.
If they chose to cancel the old one and continue creating the new one, the handler has to try again... Except this leads to a nested Try (of which I'm not fond) which essentially does the same thing the preceding code just did...
Is there a way I can remove the nested Try and just call the Handler again here? Or is there a better way of handling the situation altogether?
This would mean that the nested Try exception could also be handled more gracefully
I could leave it as is, but I have this situation cropping up in other places as well so would like to find a neater way of doing it
Thanks
Last edited by wolf99; Aug 19th, 2013 at 05:27 AM.
Thanks
-
Aug 19th, 2013, 05:22 AM
#2
Hyperactive Member
Re: Call event handler sub
You could create a function to process the widgets being added and then return a status to the key press event.
I created this very quickly to give you a basic idea.
Code:
Enum WidgetResultEnum
ADDED
ALREADYINUSE
RETRY
CANCELLED
End Enum
Private Function AddNewWidget(_strValue As String) As WidgetResultEnum
Try
' Create a new widget in the widget collection.
widgets.Add(newWidgetKey, New Widget(_strValue))
Return WidgetResultEnum.ADDED
Catch ex As AlreadyInUseException
Dim userReply As DialogResult = MessageBox.Show("Could not use that ID as it is listed as being already in use." _
+ vbNewLine + "Would you like to cancel the currentID?", _
"ID in use", MessageBoxButtons.YesNo, MessageBoxIcon.Error, _
MessageBoxDefaultButton.Button2)
If userReply = Windows.Forms.DialogResult.Yes Then
' If the user wishes to cancel the ID,
' list the widgets with that ID from the collection of current widgets.
Dim duplicateWidgets = (From widget In widgets
Where widget.Value.Id = IdBox.Text
Select widget.Key).ToList
' Check if the list has any items.
If duplicateWidgets.Count > 0 Then
' Cancel each listed widget.
For Each widgetKey As UInteger In duplicateWidgets
widgets.Item(widgetKey).CancelWidget()
Next
Return WidgetResultEnum.RETRY
End If
ElseIf userReply = Windows.Forms.DialogResult.No Then
' If the user wishes to try another Id instead,
' Select the text in the Id box, ready for attempting a new Id.
Return WidgetResultEnum.CANCELLED
End If
End Try
End Function
Private Sub IdBox_KeyPress(sender As System.Object, e As System.Windows.Forms.KeyPressEventArgs) Handles IdBox.KeyPress
' Handle any "Enter"-key presses in the Id TextBox when the entered text length is greater than 0.
If Asc(e.KeyChar) = Keys.Enter And IdBox.Text.Length > 0 Then
Do While Me.AddNewWidget(IDBox.Text) = WidgetResultEnum.RETRY
' Loop until the result is valid
Loop
Messagebox.Show("Loop Ended")
End If
End Sub
-
Aug 19th, 2013, 07:44 AM
#3
Re: Call event handler sub
I guess the question you're really asking is whether other functions and subs 'outside' the Try/Catch structure as such come under its protection to which the answer is they most certainly do. So there is no reason not to do what you always do with repeated code and create a separate sub or function.
As the 6-dimensional mathematics professor said to the brain surgeon, "It ain't Rocket Science!"
Reviews: "dunfiddlin likes his DataTables" - jmcilhinney
Please be aware that whilst I will read private messages (one day!) I am unlikely to reply to anything that does not contain offers of cash, fame or marriage!
-
Aug 19th, 2013, 09:10 AM
#4
Re: Call event handler sub
Using exception handling to catch exceptions is ALWAYS slow. Therefore, whenever possible, check for the failing situation explicitly rather than relying on an exception being thrown. This is an excellent case of that. The Widget appears to be a Dictionary, and if it is not, it certainly could be. The Dictionary has a method called ContainsKey. Therefore, you can get rid of the exception handling with this construct:
Code:
If widgets.ContainsKey(newWidgetKey) Then
'The key is already in there, do something else
Else
'Add the widget
End If
This will have noticeably better performance because exception catching can be slow enough to see it.
As a rule, if the problem isn't exceptional, but can be predicted, then do so. In this case, you can determine whether or not the addition will fail by checking to see whether or not the dictionary already contains the key.
My usual boring signature: Nothing
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|