By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,850 Members | 970 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,850 IT Pros & Developers. It's quick & easy.

Validating Event in a UserControl

P: n/a
I am experiencing some strange behavior between a UserControl's validating event and a treeview control. Initially, I thought it was related to an issue in the Knowledgebase article 810852 (http://support.microsoft.com/kb/810852), but then I realized that the hotfix mentioned was in .Net v1.1, which I am using.

I took the sample from that article and recreated the situation I see in my application. (Code included below.)

If you run the enclosed application and initially navigate to Tab2 and in the text box type an "A" (no quotes), then click on the plus sign next to the node labeled root, you get a message box as expected. Click OK in that dialog box and in the results textbox you see that a "before select", and "after select" event fired in the tree control and THEN the validating event in the textbox on Tab2 fired (it displays the word "Cancel"). Click the plus sign again and click ok in the dialog box. This time ONLY the validating event fires, none of the tree view events fire. Now wait, it gets stranger!!

Now close the app and run it again. This time, first click on the plus sign next to the root node. Now go to tab 2 and in the text box type an "A". (no quotes). Now click on the same plus sign next to the root node again. This time only the validating event fires. Click on the plus sign next to either child node. Again, only the validating event fires.

Now my question, if a validating event sets e.cancel to true why would ANY subsequent event handlers fire? Actually looking at the results it seems that in the first test the "before select" and "after select" events fired BEFORE the validating event on tab2, and the only the "before expand" event was inhibited by the e.cancel.

I would think that all validating events would get precedence and other events would not fire until the validating events were complete. And that does indeed seem to be the case on subsequent clicks in the first test case and on ALL clicks in the second test case.

This has just about driven me nuts, (yeah I know it's not a drive it's a short walk). I am using a tree as a navigation element and after the user changes data on the tab pages I attempt to update the database. On constraint errors, I don't want the user to be able to navigate away from the tab. But if the tree events are allowed to fire that is EXACTLY what will happen. The user will be allowed to navigate away from the existing tab and pending changes will be lost.

Can anyone shed some light on this?

Gary Shell
________________
code sample:
Public Class Form1

Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

Public Sub New()

MyBase.New()

'This call is required by the Windows Form Designer.

InitializeComponent()

'Add any initialization after the InitializeComponent() call

End Sub

'Form overrides dispose to clean up the component list.

Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)

If disposing Then

If Not (components Is Nothing) Then

components.Dispose()

End If

End If

MyBase.Dispose(disposing)

End Sub

'Required by the Windows Form Designer

Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Windows Form Designer

'It can be modified using the Windows Form Designer.

'Do not modify it using the code editor.

Friend WithEvents UserControl11 As WindowsApplication1.UserControl1

Friend WithEvents TreeView1 As System.Windows.Forms.TreeView

Public WithEvents Results As System.Windows.Forms.TextBox

<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

Me.UserControl11 = New WindowsApplication1.UserControl1

Me.TreeView1 = New System.Windows.Forms.TreeView

Me.Results = New System.Windows.Forms.TextBox

Me.SuspendLayout()

'

'UserControl11

'

Me.UserControl11.Location = New System.Drawing.Point(216, 16)

Me.UserControl11.Name = "UserControl11"

Me.UserControl11.Size = New System.Drawing.Size(320, 240)

Me.UserControl11.TabIndex = 0

'

'TreeView1

'

Me.TreeView1.ImageIndex = -1

Me.TreeView1.Location = New System.Drawing.Point(32, 16)

Me.TreeView1.Name = "TreeView1"

Me.TreeView1.Nodes.AddRange(New System.Windows.Forms.TreeNode() {New System.Windows.Forms.TreeNode("root", New System.Windows.Forms.TreeNode() {New System.Windows.Forms.TreeNode("child 1", New System.Windows.Forms.TreeNode() {New System.Windows.Forms.TreeNode("grandchild1")}), New System.Windows.Forms.TreeNode("child2", New System.Windows.Forms.TreeNode() {New System.Windows.Forms.TreeNode("grandchild 2")})})})

Me.TreeView1.SelectedImageIndex = -1

Me.TreeView1.Size = New System.Drawing.Size(136, 112)

Me.TreeView1.TabIndex = 3

'

'Results

'

Me.Results.Location = New System.Drawing.Point(32, 144)

Me.Results.Multiline = True

Me.Results.Name = "Results"

Me.Results.ScrollBars = System.Windows.Forms.ScrollBars.Vertical

Me.Results.Size = New System.Drawing.Size(136, 104)

Me.Results.TabIndex = 4

Me.Results.Text = ""

'

'Form1

'

Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)

Me.ClientSize = New System.Drawing.Size(568, 266)

Me.Controls.Add(Me.Results)

Me.Controls.Add(Me.TreeView1)

Me.Controls.Add(Me.UserControl11)

Me.Name = "Form1"

Me.Text = "Form1"

Me.ResumeLayout(False)

End Sub

#End Region

Private Sub TreeView1_BeforeSelect(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewCancelEventArgs) Handles TreeView1.BeforeSelect

results.Text = results.Text & "before select" & vbCrLf

End Sub

Private Sub TreeView1_AfterSelect(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles TreeView1.AfterSelect

results.Text = results.Text & "after select" & vbCrLf

End Sub

Private Sub TreeView1_BeforeExpand(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewCancelEventArgs) Handles TreeView1.BeforeExpand

results.Text = results.Text & "before expand" & vbCrLf

End Sub

End Class

-----------------------------------

Public Class UserControl1

Inherits System.Windows.Forms.UserControl

#Region " Windows Form Designer generated code "

Public Sub New()

MyBase.New()

'This call is required by the Windows Form Designer.

InitializeComponent()

'Add any initialization after the InitializeComponent() call

End Sub

'UserControl1 overrides dispose to clean up the component list.

Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)

If disposing Then

If Not (components Is Nothing) Then

components.Dispose()

End If

End If

MyBase.Dispose(disposing)

End Sub

'Required by the Windows Form Designer

Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Windows Form Designer

'It can be modified using the Windows Form Designer.

'Do not modify it using the code editor.

Friend WithEvents TabControl1 As System.Windows.Forms.TabControl

Friend WithEvents TabPage1 As System.Windows.Forms.TabPage

Friend WithEvents TabPage2 As System.Windows.Forms.TabPage

Friend WithEvents UserControl21 As WindowsApplication1.UserControl2

<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

Me.TabControl1 = New System.Windows.Forms.TabControl

Me.TabPage1 = New System.Windows.Forms.TabPage

Me.TabPage2 = New System.Windows.Forms.TabPage

Me.UserControl21 = New WindowsApplication1.UserControl2

Me.TabControl1.SuspendLayout()

Me.TabPage2.SuspendLayout()

Me.SuspendLayout()

'

'TabControl1

'

Me.TabControl1.Controls.Add(Me.TabPage1)

Me.TabControl1.Controls.Add(Me.TabPage2)

Me.TabControl1.Location = New System.Drawing.Point(8, 8)

Me.TabControl1.Name = "TabControl1"

Me.TabControl1.SelectedIndex = 0

Me.TabControl1.Size = New System.Drawing.Size(304, 216)

Me.TabControl1.TabIndex = 0

'

'TabPage1

'

Me.TabPage1.Location = New System.Drawing.Point(4, 22)

Me.TabPage1.Name = "TabPage1"

Me.TabPage1.Size = New System.Drawing.Size(296, 190)

Me.TabPage1.TabIndex = 0

Me.TabPage1.Text = "TabPage1"

'

'TabPage2

'

Me.TabPage2.Controls.Add(Me.UserControl21)

Me.TabPage2.Location = New System.Drawing.Point(4, 22)

Me.TabPage2.Name = "TabPage2"

Me.TabPage2.Size = New System.Drawing.Size(296, 190)

Me.TabPage2.TabIndex = 1

Me.TabPage2.Text = "TabPage2"

'

'UserControl21

'

Me.UserControl21.Location = New System.Drawing.Point(24, 24)

Me.UserControl21.Name = "UserControl21"

Me.UserControl21.TabIndex = 0

'

'UserControl1

'

Me.Controls.Add(Me.TabControl1)

Me.Name = "UserControl1"

Me.Size = New System.Drawing.Size(320, 240)

Me.TabControl1.ResumeLayout(False)

Me.TabPage2.ResumeLayout(False)

Me.ResumeLayout(False)

End Sub

#End Region

End Class

------------------------------------

Public Class UserControl2

Inherits System.Windows.Forms.UserControl

#Region " Windows Form Designer generated code "

Public Sub New()

MyBase.New()

'This call is required by the Windows Form Designer.

InitializeComponent()

'Add any initialization after the InitializeComponent() call

End Sub

'UserControl overrides dispose to clean up the component list.

Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)

If disposing Then

If Not (components Is Nothing) Then

components.Dispose()

End If

End If

MyBase.Dispose(disposing)

End Sub

'Required by the Windows Form Designer

Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Windows Form Designer

'It can be modified using the Windows Form Designer.

'Do not modify it using the code editor.

Friend WithEvents TextBox1 As System.Windows.Forms.TextBox

<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

Me.TextBox1 = New System.Windows.Forms.TextBox

Me.SuspendLayout()

'

'TextBox1

'

Me.TextBox1.Location = New System.Drawing.Point(8, 40)

Me.TextBox1.Name = "TextBox1"

Me.TextBox1.Size = New System.Drawing.Size(128, 20)

Me.TextBox1.TabIndex = 0

Me.TextBox1.Text = "TextBox1"

'

'UserControl2

'

Me.Controls.Add(Me.TextBox1)

Me.Name = "UserControl2"

Me.ResumeLayout(False)

End Sub

#End Region

Private Sub UserControl2_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Validating

If LCase(TextBox1.Text) = "a" Then

MessageBox.Show("Invalid entry. Reenter data again.")

e.Cancel = True

Dim myform As Form1

myform = Me.Parent.Parent.Parent.Parent

'the parent is the tab page, its parent is the tab control,

'its parent is the usercontrol and its parent is the form. Whew!

myform.Results.Text = myform.Results.Text & "Cancel" & vbCrLf

Else

e.Cancel = False

End If

End Sub

End Class

Nov 21 '05 #1
Share this question for a faster answer!
Share on Google+

This discussion thread is closed

Replies have been disabled for this discussion.