I have a TabControl with multiple TabPages which each contain multiple controls. When a user moves away from my tab using a button, I want to validate that the controls on that tab were modified correctly. Specifically, I want to check that they have selected a radio button.
What happens is that if validation fails (meaning, I set CancelEventArgs to true), the UI doesn't respond to input anymore. Controls still respond to hover and click (meaning, the color changes), but no action is taken. I can't navigate to other tabs, or even close the app using the "X" button.
I've tried adding an errorProvider, adding a SelectTab call, adding a Focus() call to both the tab and a control on the tab, and adding a MessageBox. The MessageBox allowed me to click OK, but then returned me to the "locked" UI. Adding the Focus() call to a control on the current tab (that failed validation) causes the next control to be selected, but the UI is still locked.
Any ideas why this is happening or how to get around it?
NOTE: This only happens if I try to change the tab using a button on the tab. If I just click on another tab, the cancellation works and I'm dropped back to my tab as expected with all controls usable.
EDIT: I've finally had time to revisit this. I created a simple 2 tab control with checkboxes that cancel the validation. I threw some other controls (radio buttons and text boxes) on the tabs to demonstrate the "locking", but they're not included here as there is no code behind them. This code illustrates the problem I'm having. Upon checking the checkbox and clicking button1, all controls become unresponsive. Code follows. Project files available on request.
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 TabEventTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
tabControl1.SelectedIndex++;
}
private void button2_Click(object sender, EventArgs e)
{
tabControl1.SelectedIndex--;
}
private void tabPage2_Validating(object sender, CancelEventArgs e)
{
if (checkBox2.Checked)
{
e.Cancel = true;
}
}
private void tabPage1_Validating(object sender, CancelEventArgs e)
{
if (checkBox1.Checked)
{
e.Cancel = true;
}
}
}
}
After much research, I've come to the conclusion that this cannot be done using events raised at the TabPage level. I found one MSDN forum post from 2006 that was similar to my problem and the conclusion there was that this was a bug in the .NET framework. If that's true, it still hasn't been fixed from what I can see.
The way I accomplished the validation was by using the Deselecting Event on the TabControl. This means I have one event handler for all my tabs (and I then have custom validation functions that fire based on the tab being deselected), which is not as clean as I'd like, but it's functional. I couldn't use the Selecting Event as previously suggested as that only gave me the tab I was navigating TO, and I needed to validate the tab I was leaving FROM. I missed the existence of Deselecting the first time around.
Code from my event handler: