Knowledge.ToString()

VB .Net to C# Conversion – RadioButton.CheckedChanged Event Not Firing

Radio Button CheckedChanged event not firing in C# but fires in VB .Net

In your Winforms application you have a radio button. If the user changes the value, you want to get notified. You will use RadioButton.CheckedChanged event. Your code works fine but here is a problem.

The programming language you use determines when this event will be fired for the first time. If you are using VB .Net and you have Checked = True set at design time, as soon as the control is initialized, this event will be automatically fired. Subsequently, any user interaction or change to Checked value programmatically will also fire the event.

If you are using C#, this event will not fire upon form load. CheckedChanged event will be fired only after user makes selection change or Checked value is programmatically changed after control is initialized.

In order to verify this issue, I have created a sample C# and VB .Net project. I have added a group box and two radio buttons within it. I have added CheckedChanged event to both the radio buttons.

How VB .NET Uses RadioButton.CheckedChanged Event?

Here is my VB .Net form code.

Public Class Form1
    Private Sub RadioButton1_CheckedChanged(sender As Object, e As EventArgs) Handles RadioButton1.CheckedChanged
        MessageBox.Show("1 changed:" & RadioButton1.Checked)
    End Sub

    Private Sub RadioButton2_CheckedChanged(sender As Object, e As EventArgs) Handles RadioButton2.CheckedChanged
        MessageBox.Show("2 changed:" & RadioButton2.Checked)
    End Sub
End Class

When VB compiler compiles this code, the above code is converted to following code:

<DesignerGenerated>
Public Class Form1
	Inherits Form
	Private components As IContainer

	Friend Overridable Property GroupBox1 As GroupBox

	Friend Overridable Property RadioButton1 As RadioButton
		Get
			stackVariable1 = Me._RadioButton1
			Return stackVariable1
		End Get
		<MethodImpl(MethodImplOptions.Synchronized)>
		Set(ByVal value As System.Windows.Forms.RadioButton)
			Dim eventHandler As System.EventHandler = New System.EventHandler(AddressOf Me.RadioButton1_CheckedChanged)
			Dim radioButton As System.Windows.Forms.RadioButton = Me._RadioButton1
			If (radioButton IsNot Nothing) Then
				RemoveHandler radioButton.CheckedChanged,  eventHandler
			End If
			Me._RadioButton1 = value
			radioButton = Me._RadioButton1
			If (radioButton IsNot Nothing) Then
				AddHandler radioButton.CheckedChanged,  eventHandler
			End If
		End Set
	End Property

	Friend Overridable Property RadioButton2 As RadioButton
		Get
			stackVariable1 = Me._RadioButton2
			Return stackVariable1
		End Get
		<MethodImpl(MethodImplOptions.Synchronized)>
		Set(ByVal value As System.Windows.Forms.RadioButton)
			Dim eventHandler As System.EventHandler = New System.EventHandler(AddressOf Me.RadioButton2_CheckedChanged)
			Dim radioButton As System.Windows.Forms.RadioButton = Me._RadioButton2
			If (radioButton IsNot Nothing) Then
				RemoveHandler radioButton.CheckedChanged,  eventHandler
			End If
			Me._RadioButton2 = value
			radioButton = Me._RadioButton2
			If (radioButton IsNot Nothing) Then
				AddHandler radioButton.CheckedChanged,  eventHandler
			End If
		End Set
	End Property

	Public Sub New()
		MyBase.New()
		Me.InitializeComponent()
	End Sub

	<DebuggerNonUserCode>
	Protected Overrides Sub Dispose(ByVal disposing As Boolean)
		Try
			If (If(Not disposing, False, Me.components IsNot Nothing)) Then
				Me.components.Dispose()
			End If
		Finally
			MyBase.Dispose(disposing)
		End Try
	End Sub

	<DebuggerStepThrough>
	Private Sub InitializeComponent()
		Me.GroupBox1 = New GroupBox()
		Me.RadioButton1 = New RadioButton()
		Me.RadioButton2 = New RadioButton()
		Me.GroupBox1.SuspendLayout()
		MyBase.SuspendLayout()
		Me.GroupBox1.Controls.Add(Me.RadioButton2)
		Me.GroupBox1.Controls.Add(Me.RadioButton1)
		Me.GroupBox1.Location = New Point(360, 108)
		Me.GroupBox1.Name = "GroupBox1"
		Me.GroupBox1.Size = New Size(200, 100)
		Me.GroupBox1.TabIndex = 0
		Me.GroupBox1.TabStop = False
		Me.GroupBox1.Text = "GroupBox1"
		Me.RadioButton1.AutoSize = True
		Me.RadioButton1.Location = New Point(18, 29)
		Me.RadioButton1.Name = "RadioButton1"
		Me.RadioButton1.Size = New Size(90, 17)
		Me.RadioButton1.TabIndex = 0
		Me.RadioButton1.TabStop = True
		Me.RadioButton1.Text = "RadioButton1"
		Me.RadioButton1.UseVisualStyleBackColor = True
		Me.RadioButton2.AutoSize = True
		Me.RadioButton2.Location = New Point(18, 62)
		Me.RadioButton2.Name = "RadioButton2"
		Me.RadioButton2.Size = New Size(90, 17)
		Me.RadioButton2.TabIndex = 1
		Me.RadioButton2.TabStop = True
		Me.RadioButton2.Text = "RadioButton2"
		Me.RadioButton2.UseVisualStyleBackColor = True
		MyBase.AutoScaleDimensions = New SizeF(6!, 13!)
		MyBase.AutoScaleMode = AutoScaleMode.Font
		MyBase.ClientSize = New Size(800, 450)
		MyBase.Controls.Add(Me.GroupBox1)
		MyBase.Name = "Form1"
		Me.Text = "Form1"
		Me.GroupBox1.ResumeLayout(False)
		Me.GroupBox1.PerformLayout()
		MyBase.ResumeLayout(False)
	End Sub

	Private Sub RadioButton1_CheckedChanged(ByVal sender As Object, ByVal e As EventArgs)
		MessageBox.Show(String.Concat("1 changed:", Conversions.ToString(Me.RadioButton1.Checked)))
	End Sub

	Private Sub RadioButton2_CheckedChanged(ByVal sender As Object, ByVal e As EventArgs)
		MessageBox.Show(String.Concat("2 changed:", Conversions.ToString(Me.RadioButton2.Checked)))
	End Sub
End Class

As you noticed, InitializeComponent function initialized RadioButton and at the same time the event handler gets attached to the radio button. Design time value is set after the handler is attached and hence the event is fired as soon control is initialized.

How C# Uses RadioButton.CheckedChanged Event?

Here is my C# Code.

public partial class Form1 : Form
{
	public Form1()
	{
		InitializeComponent();
	}

	private void radioButton1_CheckedChanged(object sender, EventArgs e)
	{
		MessageBox.Show("1 changed to " +  radioButton1.Checked);
	}

	private void radioButton2_CheckedChanged(object sender, EventArgs e)
	{
		MessageBox.Show("2 changed to " + radioButton2.Checked);
	}
}

When C# compiler compiles this code, the above code is converted to following code:

public class Form1 : Form
{
	private IContainer components = null;

	private GroupBox groupBox1;

	private RadioButton radioButton2;

	private RadioButton radioButton1;

	public Form1()
	{
		this.InitializeComponent();
	}

	protected override void Dispose(bool disposing)
	{
		if ((!disposing ? false : this.components != null))
		{
			this.components.Dispose();
		}
		base.Dispose(disposing);
	}

	private void InitializeComponent()
	{
		this.groupBox1 = new GroupBox();
		this.radioButton1 = new RadioButton();
		this.radioButton2 = new RadioButton();
		this.groupBox1.SuspendLayout();
		base.SuspendLayout();
		this.groupBox1.Controls.Add(this.radioButton2);
		this.groupBox1.Controls.Add(this.radioButton1);
		this.groupBox1.Location = new Point(352, 75);
		this.groupBox1.Name = "groupBox1";
		this.groupBox1.Size = new Size(200, 100);
		this.groupBox1.TabIndex = 0;
		this.groupBox1.TabStop = false;
		this.groupBox1.Text = "groupBox1";
		this.radioButton1.AutoSize = true;
		this.radioButton1.Checked = true;
		this.radioButton1.Location = new Point(7, 20);
		this.radioButton1.Name = "radioButton1";
		this.radioButton1.Size = new Size(85, 17);
		this.radioButton1.TabIndex = 0;
		this.radioButton1.TabStop = true;
		this.radioButton1.Text = "radioButton1";
		this.radioButton1.UseVisualStyleBackColor = true;
		this.radioButton1.CheckedChanged += new EventHandler(this.radioButton1_CheckedChanged);
		this.radioButton2.AutoSize = true;
		this.radioButton2.Location = new Point(7, 44);
		this.radioButton2.Name = "radioButton2";
		this.radioButton2.Size = new Size(85, 17);
		this.radioButton2.TabIndex = 1;
		this.radioButton2.Text = "radioButton2";
		this.radioButton2.UseVisualStyleBackColor = true;
		this.radioButton2.CheckedChanged += new EventHandler(this.radioButton2_CheckedChanged);
		base.AutoScaleDimensions = new SizeF(6f, 13f);
		base.AutoScaleMode = AutoScaleMode.Font;
		base.ClientSize = new Size(800, 450);
		base.Controls.Add(this.groupBox1);
		base.Name = "Form1";
		this.Text = "Form1";
		this.groupBox1.ResumeLayout(false);
		this.groupBox1.PerformLayout();
		base.ResumeLayout(false);
	}

	private void radioButton1_CheckedChanged(object sender, EventArgs e)
	{
		bool @checked = this.radioButton1.Checked;
		MessageBox.Show(string.Concat("1 changed to ", @checked.ToString()));
	}

	private void radioButton2_CheckedChanged(object sender, EventArgs e)
	{
		bool @checked = this.radioButton1.Checked;
		MessageBox.Show(string.Concat("2 changed to ", @checked.ToString()));
	}
}

The C# compiler compiles the code in such a way that event handle is attached to the radio button after the design time value is set. Hence the event will not be fired when control is initialized.

Share

Comments

One response to “VB .Net to C# Conversion – RadioButton.CheckedChanged Event Not Firing”

  1. Convert WinForms and Web Application VB .NET Projects to C# – Vishal Monpara

    […] In VB .Net RadioButton.CheckedChanged is fired for the first time on form load. In C#, the same event gets fired only when you programmatically change the value or user selects a radio button. Difference in the way CheckedChanged is fired is caused by the way VB and C# Compiler generates code. […]

Leave a Reply

Your email address will not be published. Required fields are marked *