c# stop user changing tab on tab control stops events

  • Thread starter Thread starter k.mellor
  • Start date Start date
K

k.mellor

All,

I am trying to stop users changing tab pages on a tab control if the
tab page has not been validated. This I can do by adding a tab
control selected index change event handler and a tab page validating
event handler.

http://www.syncfusion.com/FAQ/winforms/FAQ_c93c.aspx#q958q

However, once validation has failed, no other events are thrown by
controls on the same tab page until the tab page has lost and then
regained focus. I have attached sample code for a simple form.
Uncheck the test box, try to change to tab 2, and then try and click
the Tab Button. It does not fire. But it does if you click Form
button first.

Can anyone suggest a solution to this. I have kept the sample code as
simple as possible.

Thanks in advance - code below.



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace TabSample
{

public class Form1 : Form
{

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}

/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;

private TabControl tabControl1;
private TabPage tabPage1;
private Button btnTabButton;
private CheckBox cbName;
private TabPage tabPage2;
private Button btnFormButton;

/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should
be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (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.tabControl1 = new System.Windows.Forms.TabControl();
this.tabPage1 = new System.Windows.Forms.TabPage();
this.tabPage2 = new System.Windows.Forms.TabPage();
this.cbName = new System.Windows.Forms.CheckBox();
this.btnTabButton = new System.Windows.Forms.Button();
this.btnFormButton = new System.Windows.Forms.Button();
this.tabControl1.SuspendLayout();
this.tabPage1.SuspendLayout();
this.SuspendLayout();
//
// tabControl1
//
this.tabControl1.Controls.Add(this.tabPage1);
this.tabControl1.Controls.Add(this.tabPage2);
this.tabControl1.Location = new System.Drawing.Point(41,
12);
this.tabControl1.Name = "tabControl1";
this.tabControl1.SelectedIndex = 0;
this.tabControl1.Size = new System.Drawing.Size(376, 249);
this.tabControl1.TabIndex = 0;
this.tabControl1.SelectedIndexChanged += new
System.EventHandler(this.tabControl1_SelectedIndexChanged);
//
// tabPage1
//
this.tabPage1.Controls.Add(this.btnTabButton);
this.tabPage1.Controls.Add(this.cbName);
this.tabPage1.Location = new System.Drawing.Point(4, 22);
this.tabPage1.Name = "tabPage1";
this.tabPage1.Padding = new
System.Windows.Forms.Padding(3);
this.tabPage1.Size = new System.Drawing.Size(368, 223);
this.tabPage1.TabIndex = 0;
this.tabPage1.Text = "tabPage1";
this.tabPage1.UseVisualStyleBackColor = true;
this.tabPage1.Validating += new
System.ComponentModel.CancelEventHandler(this.tabPage1_Validating);
//
// tabPage2
//
this.tabPage2.Location = new System.Drawing.Point(4, 22);
this.tabPage2.Name = "tabPage2";
this.tabPage2.Padding = new
System.Windows.Forms.Padding(3);
this.tabPage2.Size = new System.Drawing.Size(192, 74);
this.tabPage2.TabIndex = 1;
this.tabPage2.Text = "tabPage2";
this.tabPage2.UseVisualStyleBackColor = true;
//
// cbName
//
this.cbName.AutoSize = true;
this.cbName.Checked = true;
this.cbName.CheckState =
System.Windows.Forms.CheckState.Checked;
this.cbName.Location = new System.Drawing.Point(40, 57);
this.cbName.Name = "cbName";
this.cbName.Size = new System.Drawing.Size(55, 17);
this.cbName.TabIndex = 0;
this.cbName.Text = "Valid?";
this.cbName.UseVisualStyleBackColor = true;
//
// btnTabButton
//
this.btnTabButton.Location = new System.Drawing.Point(121,
142);
this.btnTabButton.Name = "btnTabButton";
this.btnTabButton.Size = new System.Drawing.Size(75, 23);
this.btnTabButton.TabIndex = 1;
this.btnTabButton.Text = "Tab Button";
this.btnTabButton.UseVisualStyleBackColor = true;
this.btnTabButton.Click += new
System.EventHandler(this.btnTabButton_Click);
//
// btnFormButton
//
this.btnFormButton.Location = new
System.Drawing.Point(166, 302);
this.btnFormButton.Name = "btnFormButton";
this.btnFormButton.Size = new System.Drawing.Size(75, 23);
this.btnFormButton.TabIndex = 1;
this.btnFormButton.Text = "Form Button";
this.btnFormButton.UseVisualStyleBackColor = true;
this.btnFormButton.Click += new
System.EventHandler(this.btnFormButton_Click);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F,
13F);
this.AutoScaleMode =
System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(458, 348);
this.Controls.Add(this.btnFormButton);
this.Controls.Add(this.tabControl1);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.tabControl1.ResumeLayout(false);
this.tabPage1.ResumeLayout(false);
this.tabPage1.PerformLayout();
this.ResumeLayout(false);

}

#endregion

/// <summary>
/// COnstructor
/// </summary>
public Form1()
{
InitializeComponent();
}


/// <summary>
/// Handle button on form
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnFormButton_Click(object sender, EventArgs e)
{
MessageBox.Show("Form Button Clicked");
}

/// <summary>
/// Handle button on tab page
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnTabButton_Click(object sender, EventArgs e)
{
MessageBox.Show("Tab Button Clicked");
}

/// <summary>
/// Tab control event handler
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void tabControl1_SelectedIndexChanged(object sender,
EventArgs e)
{
tabControl1.TabPages[tabControl1.SelectedIndex].Focus();

tabControl1.TabPages[tabControl1.SelectedIndex].CausesValidation =
true;
}

private void Form1_Load(object sender, EventArgs e)
{
tabControl1.TabPages[0].Focus();
tabControl1.TabPages[0].CausesValidation = true;
}

/// <summary>
/// Validate tab page
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void tabPage1_Validating(object sender,
CancelEventArgs e)
{
if (!this.cbName.Checked)
{
MessageBox.Show("Tab not valid - not leaving");
e.Cancel = true;
}
}

} // end of class

} // end of namespace
 
Apologies - slight correction.

Once the tab page validation has failed, even after clicking the
button on the form, the check box and button on the tab page do not
function.

Any ideas?
 
UPDATE
=======

Still no solution but I am nearer an explanation. I found this on
MSDN

http://msdn.microsoft.com/en-us/library/system.windows.forms.control.validating.aspx

If the Cancel property of the CancelEventArgs is set to true in the
Validating event delegate, all events that would usually occur after
the Validating event are suppressed.


This goes someway to explaining the behaviour. In my mind, the Tab
Button cannot regain focus, and focus must be obtained before the
click event is fired (I maybe be wrong but this is not too important
for the current problem).

The challenge now is how do I get the form to do what I want?

All input appreciated.
 
There are better ways of preventing a tab change. See the following post:
http://groups.google.co.uk/group/microsoft.public.dotnet.framework.windowsforms/msg/21e56fa2df4bd095

The code in it is VB.NET but should be trivial to translate

/claes

All,

I am trying to stop users changing tab pages on a tab control if the
tab page has not been validated. This I can do by adding a tab
control selected index change event handler and a tab page validating
event handler.

http://www.syncfusion.com/FAQ/winforms/FAQ_c93c.aspx#q958q

However, once validation has failed, no other events are thrown by
controls on the same tab page until the tab page has lost and then
regained focus. I have attached sample code for a simple form.
Uncheck the test box, try to change to tab 2, and then try and click
the Tab Button. It does not fire. But it does if you click Form
button first.

Can anyone suggest a solution to this. I have kept the sample code as
simple as possible.

Thanks in advance - code below.



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace TabSample
{

public class Form1 : Form
{

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}

/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;

private TabControl tabControl1;
private TabPage tabPage1;
private Button btnTabButton;
private CheckBox cbName;
private TabPage tabPage2;
private Button btnFormButton;

/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should
be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (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.tabControl1 = new System.Windows.Forms.TabControl();
this.tabPage1 = new System.Windows.Forms.TabPage();
this.tabPage2 = new System.Windows.Forms.TabPage();
this.cbName = new System.Windows.Forms.CheckBox();
this.btnTabButton = new System.Windows.Forms.Button();
this.btnFormButton = new System.Windows.Forms.Button();
this.tabControl1.SuspendLayout();
this.tabPage1.SuspendLayout();
this.SuspendLayout();
//
// tabControl1
//
this.tabControl1.Controls.Add(this.tabPage1);
this.tabControl1.Controls.Add(this.tabPage2);
this.tabControl1.Location = new System.Drawing.Point(41,
12);
this.tabControl1.Name = "tabControl1";
this.tabControl1.SelectedIndex = 0;
this.tabControl1.Size = new System.Drawing.Size(376, 249);
this.tabControl1.TabIndex = 0;
this.tabControl1.SelectedIndexChanged += new
System.EventHandler(this.tabControl1_SelectedIndexChanged);
//
// tabPage1
//
this.tabPage1.Controls.Add(this.btnTabButton);
this.tabPage1.Controls.Add(this.cbName);
this.tabPage1.Location = new System.Drawing.Point(4, 22);
this.tabPage1.Name = "tabPage1";
this.tabPage1.Padding = new
System.Windows.Forms.Padding(3);
this.tabPage1.Size = new System.Drawing.Size(368, 223);
this.tabPage1.TabIndex = 0;
this.tabPage1.Text = "tabPage1";
this.tabPage1.UseVisualStyleBackColor = true;
this.tabPage1.Validating += new
System.ComponentModel.CancelEventHandler(this.tabPage1_Validating);
//
// tabPage2
//
this.tabPage2.Location = new System.Drawing.Point(4, 22);
this.tabPage2.Name = "tabPage2";
this.tabPage2.Padding = new
System.Windows.Forms.Padding(3);
this.tabPage2.Size = new System.Drawing.Size(192, 74);
this.tabPage2.TabIndex = 1;
this.tabPage2.Text = "tabPage2";
this.tabPage2.UseVisualStyleBackColor = true;
//
// cbName
//
this.cbName.AutoSize = true;
this.cbName.Checked = true;
this.cbName.CheckState =
System.Windows.Forms.CheckState.Checked;
this.cbName.Location = new System.Drawing.Point(40, 57);
this.cbName.Name = "cbName";
this.cbName.Size = new System.Drawing.Size(55, 17);
this.cbName.TabIndex = 0;
this.cbName.Text = "Valid?";
this.cbName.UseVisualStyleBackColor = true;
//
// btnTabButton
//
this.btnTabButton.Location = new System.Drawing.Point(121,
142);
this.btnTabButton.Name = "btnTabButton";
this.btnTabButton.Size = new System.Drawing.Size(75, 23);
this.btnTabButton.TabIndex = 1;
this.btnTabButton.Text = "Tab Button";
this.btnTabButton.UseVisualStyleBackColor = true;
this.btnTabButton.Click += new
System.EventHandler(this.btnTabButton_Click);
//
// btnFormButton
//
this.btnFormButton.Location = new
System.Drawing.Point(166, 302);
this.btnFormButton.Name = "btnFormButton";
this.btnFormButton.Size = new System.Drawing.Size(75, 23);
this.btnFormButton.TabIndex = 1;
this.btnFormButton.Text = "Form Button";
this.btnFormButton.UseVisualStyleBackColor = true;
this.btnFormButton.Click += new
System.EventHandler(this.btnFormButton_Click);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F,
13F);
this.AutoScaleMode =
System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(458, 348);
this.Controls.Add(this.btnFormButton);
this.Controls.Add(this.tabControl1);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.tabControl1.ResumeLayout(false);
this.tabPage1.ResumeLayout(false);
this.tabPage1.PerformLayout();
this.ResumeLayout(false);

}

#endregion

/// <summary>
/// COnstructor
/// </summary>
public Form1()
{
InitializeComponent();
}


/// <summary>
/// Handle button on form
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnFormButton_Click(object sender, EventArgs e)
{
MessageBox.Show("Form Button Clicked");
}

/// <summary>
/// Handle button on tab page
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnTabButton_Click(object sender, EventArgs e)
{
MessageBox.Show("Tab Button Clicked");
}

/// <summary>
/// Tab control event handler
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void tabControl1_SelectedIndexChanged(object sender,
EventArgs e)
{
tabControl1.TabPages[tabControl1.SelectedIndex].Focus();

tabControl1.TabPages[tabControl1.SelectedIndex].CausesValidation =
true;
}

private void Form1_Load(object sender, EventArgs e)
{
tabControl1.TabPages[0].Focus();
tabControl1.TabPages[0].CausesValidation = true;
}

/// <summary>
/// Validate tab page
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void tabPage1_Validating(object sender,
CancelEventArgs e)
{
if (!this.cbName.Checked)
{
MessageBox.Show("Tab not valid - not leaving");
e.Cancel = true;
}
}

} // end of class

} // end of namespace
 
Back
Top