BUG: Focus on a control that does not support the CausesValidation property suppresses validation of unvalidated controls in the user control (814350)



The information in this article applies to:

  • Microsoft .NET Framework 1.1
  • Microsoft .NET Framework 1.0
  • Microsoft Visual Basic .NET (2003)
  • Microsoft Visual Basic .NET (2002)
  • Microsoft Visual C# .NET (2003)
  • Microsoft Visual C# .NET (2002)

SYMPTOMS

The pending validation of the controls in a user control is suppressed if the following conditions are true:
  • There are multiple controls in the user control.

    -and-
  • In the user control, you move from a control with the CausesValidation property set to False to another instance of the user control.

CAUSE

When you move the focus out of the user control, only the currently active control in the user control is checked for CausesValidation. If that active control has CausesValidation set to False, the remaining unvalidated controls of the container control are not checked for CausesValidation.

STATUS

Microsoft has confirmed that this is a bug in the Microsoft products that are listed in the "Applies to" section.

MORE INFORMATION

Steps to Reproduce the Behavior

  1. Create a new Windows Application project by using Visual C# .NET or Visual Basic .NET.

    By default, Form1 is created.
  2. Right-click Form1, and then click View Code.
  3. Replace the existing code with the following code:

    Visual C# .NET Code
    using System;
    using System.Drawing;
    using System.Collections;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.Data;
    
    namespace WindowsApplication11
    {
    	/// <summary>
    	/// Summary description for Form1.
    	/// </summary>
    	public class Form1 : System.Windows.Forms.Form
    	{
    		private System.Windows.Forms.MainMenu mainMenu1;
    		private System.Windows.Forms.MenuItem menuItem1;
    		private System.Windows.Forms.MenuItem menuItem2;
    		private System.Windows.Forms.MenuItem menuItem3;
    		private System.Windows.Forms.MenuItem menuItem4;
    		/// <summary>
    		/// Required designer variable.
    		/// </summary>
    		private System.ComponentModel.Container components = null;
    
    		public Form1()
    		{
    			//
    			// Required for Windows Form Designer support.
    			//
    			InitializeComponent();
    
    			//
    			// TODO: Add any constructor code after InitializeComponent call.
    			//
    		}
    
    		/// <summary>
    		/// Clean up any resources that are being used.
    		/// </summary>
    		protected override void Dispose( bool disposing )
    		{
    			if( disposing )
    			{
    				if (components != null) 
    				{
    					components.Dispose();
    				}
    			}
    			base.Dispose( disposing );
    		}
    
    		#region Windows Form Designer generated code
    		/// <summary>
    		/// Required method for Designer support - do not modify
    		/// the contents of this method with the code editor.
    		/// </summary>
    		private void InitializeComponent()
    		{
    			this.mainMenu1 = new System.Windows.Forms.MainMenu();
    			this.menuItem1 = new System.Windows.Forms.MenuItem();
    			this.menuItem2 = new System.Windows.Forms.MenuItem();
    			this.menuItem3 = new System.Windows.Forms.MenuItem();
    			this.menuItem4 = new System.Windows.Forms.MenuItem();
    			// 
    			// mainMenu1
    			// 
    			this.mainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
    																					  this.menuItem1,
    																					  this.menuItem3,
    																					  this.menuItem2,
    																					  this.menuItem4});
    			// 
    			// menuItem1
    			// 
    			this.menuItem1.Index = 0;
    			this.menuItem1.Text = "&0";
    			this.menuItem1.Click += new System.EventHandler(this.menuItem1_Click);
    			// 
    			// menuItem2
    			// 
    			this.menuItem2.Index = 2;
    			this.menuItem2.Text = "&2";
    			this.menuItem2.Click += new System.EventHandler(this.menuItem2_Click);
    			// 
    			// menuItem3
    			// 
    			this.menuItem3.Index = 1;
    			this.menuItem3.Text = "&1";
    			this.menuItem3.Click += new System.EventHandler(this.menuItem3_Click);
    			// 
    			// menuItem4
    			// 
    			this.menuItem4.Index = 3;
    			this.menuItem4.Text = "&3";
    			this.menuItem4.Click += new System.EventHandler(this.menuItem4_Click);
    			// 
    			// Form1
    			// 
    			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
    			this.ClientSize = new System.Drawing.Size(292, 273);
    			this.Menu = this.mainMenu1;
    			this.Name = "Form1";
    			this.Text = "Form1";
    			this.Load += new System.EventHandler(this.Form1_Load);
    
    		}
    		#endregion
    
    		/// <summary>
    		/// The main entry point for the application.
    		/// </summary>
    		[STAThread]
    		static void Main() 
    		{
    			Application.Run(new Form1());
    		}
    
    		TextBox[] txt = new TextBox[4];
    		private void Form1_Load(object sender, System.EventArgs e)
    		{
    			UserControl uc, uc2;
    
    			uc = new UserControl();
    			uc.Size = new Size(150, 150);
    			uc.BackColor = Color.Green;
    			Controls.Add(uc);
    
    			uc2 = new UserControl();
    			uc2.Size = new Size(100, 100);
    			uc2.BackColor = Color.Red;
    			uc2.Top = uc.Bottom + 10;
    			Controls.Add(uc2);
    
    			for (int i=0; i<4; i++) 
    			{
    				txt[i] = new TextBox();
    				txt[i].Text = "TextBox" + i;
    				txt[i].Validating += new CancelEventHandler(c_Validating);
    			}
    			txt[3].Top = txt[2].Bottom + 5;
    			txt[1].Top = txt[0].Bottom + 5;
    			txt[1].CausesValidation = false;
    			txt[2].CausesValidation = false;
    			txt[1].Text += "(false)";
    			txt[2].Text += "(false)";
    			uc.Controls.AddRange(new Control[] {txt[0], txt[1]});
    			uc2.Controls.AddRange(new Control[] {txt[2], txt[3]});
    		}
    
    		void c_Validating(object o, CancelEventArgs e) 
    		{
    			Console.WriteLine("Validating " + ((Control)o).Text);
    		}
    
    		private void menuItem1_Click(object sender, System.EventArgs e)
    		{
    			txt[0].Focus();
    		}
    
    		private void menuItem2_Click(object sender, System.EventArgs e)
    		{
    			txt[2].Focus();
    		}
    
    		private void menuItem3_Click(object sender, System.EventArgs e)
    		{
    			txt[1].Focus();
    		}
    
    		private void menuItem4_Click(object sender, System.EventArgs e)
    		{
    			txt[3].Focus();
    		}
    	}
    }
    
  4. Visual Basic .NET Code
    Imports System
    Imports System.Drawing
    Imports System.Collections
    Imports System.ComponentModel
    Imports System.Windows.Forms
    Imports System.Data
    
    Public Class Form1
        Inherits System.Windows.Forms.Form
    
        Private WithEvents mainMenu1 As System.Windows.Forms.MainMenu
        Private WithEvents menuItem1 As System.Windows.Forms.MenuItem
        Private WithEvents menuItem2 As System.Windows.Forms.MenuItem
        Private WithEvents menuItem3 As System.Windows.Forms.MenuItem
        Private WithEvents menuItem4 As System.Windows.Forms.MenuItem
    
    
    #Region " Windows Form Designer generated code "
    
        Public Sub New()
            MyBase.New()
    
            'The Windows Form Designer requires this call.
            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 Windows Form Designer requires the following procedure.
        'It can be modified using the Windows Form Designer.  
        'Do not modify it using the code editor.
        <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
            Me.mainMenu1 = New System.Windows.Forms.MainMenu()
            Me.menuItem1 = New System.Windows.Forms.MenuItem()
            Me.menuItem2 = New System.Windows.Forms.MenuItem()
            Me.menuItem3 = New System.Windows.Forms.MenuItem()
            Me.menuItem4 = New System.Windows.Forms.MenuItem()
            '
            'Form1
            '
            Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
            Me.ClientSize = New System.Drawing.Size(292, 273)
            Me.Name = "Form1"
            Me.Text = "Form1"
            Me.Menu = Me.mainMenu1
    
    
    
            Me.mainMenu1.MenuItems.AddRange(New System.Windows.Forms.MenuItem() {Me.menuItem1, Me.menuItem2, Me.menuItem3, Me.menuItem4})
    
            ' menuItem1
    
            Me.menuItem1.Index = 0
            Me.menuItem1.Text = "&0"
    
            ' menuItem2
    
            Me.menuItem2.Index = 2
            Me.menuItem2.Text = "&2"
    
    
            ' menuItem3
    
            Me.menuItem3.Index = 1
            Me.menuItem3.Text = "&1"
    
    
            ' menuItem4
    
            Me.menuItem4.Index = 3
            Me.menuItem4.Text = "&3"
    
    
        End Sub
    
    #End Region
    
        Dim txt As TextBox() = New TextBox(3) {}
    
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Dim uc As UserControl = New UserControl()
            uc.Size = New Size(150, 150)
            uc.BackColor = Color.Green
            Controls.Add(uc)
    
            Dim uc2 As UserControl = New UserControl()
            uc2.Size = New Size(100, 100)
            uc2.BackColor = Color.Red
            uc2.Top = uc.Bottom + 10
            Controls.Add(uc2)
            Dim i As Integer
            For i = 0 To 3
                txt(i) = New TextBox()
                txt(i).Text = "TextBox"
                txt(i).Text = txt(i).Text & i
                AddHandler txt(i).Validating, AddressOf c_validating
            Next
    
            txt(3).Top = txt(2).Height + 5
            txt(1).Top = txt(0).Bottom + 5
            txt(1).CausesValidation = False
            txt(2).CausesValidation = False
            txt(1).Text += "(false)"
            txt(2).Text += "(false)"
            uc.Controls.AddRange(New Control() {txt(0), txt(1)})
            uc2.Controls.AddRange(New Control() {txt(2), txt(3)})
        End Sub
    
    
        Private Sub MenuItem1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles menuItem1.Click
            txt(0).Focus()
        End Sub
        Private Sub MenuItem2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles menuItem2.Click
            txt(2).Focus()
        End Sub
        Private Sub MenuItem3_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles menuItem3.Click
            txt(1).Focus()
        End Sub
        Private Sub MenuItem4_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles menuItem4.Click
            txt(3).Focus()
        End Sub
        Private Sub c_Validating(ByVal o As Object, ByVal e As CancelEventArgs)
    
            Console.WriteLine("Validating " + (o.Text))
        End Sub
        
    
    End Class
    
  5. On the File menu, click Save to save the project.
  6. On the Debug menu, click Start to run the application.

    A Windows form is displayed with a menu and two user controls. Each user control contains two TextBoxes.

    The TextBox that displays "(false)" has the CausesValidation property set to False.

    You can move among the controls if you press the TAB key or click the menu.
  7. Follow these steps, and then notice the output in the Output window:
    1. Press the TAB key two times to move to TextBox2.

      Expected Output: Validating TextBox0.
      Actual Output: Validation event for TextBox1 is suppressed.
    2. Press the TAB key two more times to move back to TextBox0.

      Expected Output: Validating TextBox3.
      Actual Output: Validating TextBox3.
    3. Press and hold down the ALT key and then press the 2 key to move to TextBox2.

      Expected Output: Validating TextBox0.
      Actual Output: Validating TextBox0.
    4. Press the TAB key or press and hold down the ALT key and then press 3.

      Expected Output: Validating TextBox3.
      Actual Output: Validation event for TextBox3 is suppressed.

REFERENCES

For more information about user controls, see the following .NET Framework software development kit (SDK) documentation:

Modification Type:MinorLast Reviewed:3/7/2006
Keywords:kbvs2005swept kbvs2005doesnotapply kbvs2002sp1sweep kbWindowsForms kbControl kbCtrl kbValidation kbbug KB814350 kbAudDeveloper