Preparing the Project and Designing the Main Window
Start by opening Visual Studio and selecting “Create a new project.” From the list of templates, pick “Windows Forms App (.NET Framework)” if you are working with the full framework, or “Windows Forms App” for .NET 6/7 depending on your environment. Name the project – for example, TestApp – and set the location on disk. Once the wizard finishes, the IDE presents a single blank form, typically calledForm1
The goal of this form is simple: it will host a button that opens a dialog, a label that displays a greeting, and a combo‑box that lets the user pick a favorite color. Drag a Button from the Toolbox onto the form. Set its Name property to btnEnterName and its Text property to Enter Name. Position it near the top‑left corner so it’s the first control the user encounters. Underneath, drop a Label and change its Name to lblGreeting and its Text to Welcome!. Finally, add a ComboBox, rename it cboFavoriteColor, and give it a width that comfortably fits four items. All three controls should be centered horizontally on the form for a tidy layout.
The ComboBox needs data. Open its Items collection and add the four color names: Red, Green, Blue, and Yellow. These values will be used later to set the dialog’s background color. In the Properties window, set the Modifiers property of the combo box to Public so it can be accessed from another form. This visibility choice keeps the code straightforward for this example; in a larger project you might prefer encapsulation and expose a property instead.
Next, wire an event to the button. Double‑click the button to generate a Click event handler in the code‑behind. For now, leave the handler empty – the logic will arrive in a later section. Still, having the method stub ready saves time when you come back to it. Likewise, add a Load event handler for the form. In this method, set the default selection of the combo box to the first item by assigning cboFavoriteColor.SelectedIndex = 0;. This ensures that a color is always selected when the dialog is shown, preventing null reference exceptions.
The form’s constructor already contains a call to InitializeComponent(), which wires up all the controls and sets their properties based on the designer. You can view this method by expanding Form1.Designer.cs. For the purposes of this tutorial, keep the designer file untouched and focus on the user‑implemented logic in Form1.cs. At this point, the main window is functional: it displays a button, a greeting label, and a combo box with four color options. The next step is to create the dialog that will gather user input and respond to the selected color.Creating the Dialog and Sharing Information
Add a second form to the solution by right‑clicking the project, choosing Add → Windows Form, and naming it Form2. The designer opens a blank canvas. The dialog will contain a single TextBox for the name, two buttons labeled OK and Cancel, and a background that adapts to the color chosen on the main form. Drag a TextBox onto the form, set its Name to txtName, and place it near the top with a margin. Give the text box a placeholder text such as “Please enter your name” by setting its Text property to that string.
Place an OK button below the text box, name it btnOk, and set its DialogResult property to OK. This single property assignment instructs the dialog to return DialogResult.OK when the button is pressed, automatically closing the form unless you override that behavior. Below the OK button, drop a Cancel button, name it btnCancel, and set its DialogResult to Cancel. The combination of two buttons with these properties allows the calling code to differentiate between a confirmed name and a dismissal.
To pass data between the two windows, add a public field named MyParentForm of type Form1 to Form2. Though exposing the parent form as a public field is simple, consider using a read‑only property or constructor injection in larger applications to avoid tight coupling. In the same class, expose a read‑only property UserName that returns the current text in txtName. This encapsulates the control’s value and provides a clean interface for the parent form to retrieve the user’s input after the dialog closes.
The dialog’s background color must reflect the selection made in the combo box on the main form. To achieve this, handle the Load event of Form2. Inside the event handler, cast the MyParentForm field to Form1 and read the selected item of its combo box. Convert the string to a Color by calling Color.FromName and assign the result to this.BackColor. This simple line ensures the dialog’s appearance changes dynamically based on user choice without hardcoding any color values.
Finally, add click handlers for both buttons that simply call Close(). Since the DialogResult properties already manage the return value, there is no need to set DialogResult explicitly in the code. By keeping the handlers minimal, you maintain a clean separation between UI and logic. At the end of this section, you have a dialog that can read the parent form’s state, present a color‑adapted interface, and expose the user’s name back to the caller.Connecting the Pieces: Showing the Dialog and Handling the Result
Return to Form1 and locate the btnEnterName_Click handler you generated earlier. Inside this method, create an instance of the dialog: var nameDialog = new Form2();. Before displaying it, assign the current form instance to the dialog’s MyParentForm field: nameDialog.MyParentForm = this;. This establishes the reference that the dialog will use to read the combo box selection during its Load event.
Display the dialog modally by calling nameDialog.ShowDialog(). Because ShowDialog() returns a DialogResult, compare the result to DialogResult.OK. If the comparison succeeds, the user pressed the OK button and a name was entered. Retrieve the name via the dialog’s UserName property and update the main form’s greeting label: lblGreeting.Text = $"Hello {nameDialog.UserName}";. Use string interpolation for readability and to avoid concatenation pitfalls. If the result is DialogResult.Cancel, leave the label unchanged or display a generic greeting such as lblGreeting.Text = "Hello Guest";. This logic captures both user paths and updates the UI accordingly.
The modal nature of ShowDialog() blocks interaction with Form1 until the user dismisses the dialog. This guarantees that the dialog runs to completion before control returns to the click handler. It also simplifies the flow: you don’t need to track whether the dialog is open or closed elsewhere. When the dialog closes, the lblGreeting is updated, and the main form remains responsive to additional actions. This pattern - instantiate, configure, show modally, and process the result - is the most common way to manage dialog interactions in Windows Forms.
During development, you might encounter scenarios where the user clicks OK without entering a name. Because the UserName property simply returns whatever is typed in the text box, you could add validation inside the dialog or in the click handler. For example, check if string.IsNullOrWhiteSpace(nameDialog.UserName) and, if true, display a message box prompting the user to enter a name before closing. This defensive programming keeps the application robust and user‑friendly.
To test the flow, run the application. Click Enter Name to bring up the dialog. Select a color from the combo box before opening the dialog; notice the dialog’s background matches that selection. Type a name, click OK, and observe the greeting label update. Try clicking Cancel and verify that the label says “Hello Guest.” Repeat the test with different colors to confirm that the dialog adapts each time. Once satisfied, you’ve successfully wired two forms together, passed data in both directions, and implemented a clean dialog workflow.Complete Code Listing and Practical Takeaways
Below is the full source for both forms, presented in a compact but readable style. The code follows standard .NET naming conventions, uses string interpolation, and avoids unnecessary comments that clutter the view. Feel free to copy, paste, and run it directly in Visual Studio or Visual Studio Code with the .NET desktop workload installed.
Form1.cs
using System;</p>
<p>using System.Drawing;</p>
<p>using System.Windows.Forms;</p>
<p>namespace TestApp</p>
<p>{</p>
<p>
public partial class Form1 : Form</p>
<p>
{</p>
<p>
public Form1()</p>
<p>
{</p>
<p>
InitializeComponent();</p>
<p>
}</p>
<p>
private void btnEnterName_Click(object sender, EventArgs e)</p>
<p>
{</p>
<p>
using var dialog = new Form2 { MyParentForm = this };</p>
<p>
if (dialog.ShowDialog() == DialogResult.OK)</p>
<p>
lblGreeting.Text = $"Hello {dialog.UserName}";</p>
<p>
else</p>
<p>
lblGreeting.Text = "Hello Guest";</p>
<p>
}</p>
<p>
private void Form1_Load(object sender, EventArgs e)</p>
<p>
{</p>
<p>
cboFavoriteColor.SelectedIndex = 0;</p>
<p>
}</p>
<p>
}</p>
<p>}</p>
Form1.Designer.cs
partial class Form1</p>
<p>{</p>
<p>
private Button btnEnterName;</p>
<p>
private Label lblGreeting;</p>
<p>
public ComboBox cboFavoriteColor;</p>
<p>
private void InitializeComponent()</p>
<p>
{</p>
<p>
btnEnterName = new Button();</p>
<p>
lblGreeting = new Label();</p>
<p>
cboFavoriteColor = new ComboBox();</p>
<p>
//</p>
<p>
// btnEnterName</p>
<p>
//</p>
<p>
btnEnterName.Location = new Point(16, 8);</p>
<p>
btnEnterName.Name = "btnEnterName";</p>
<p>
btnEnterName.Size = new Size(104, 32);</p>
<p>
btnEnterName.Text = "Enter Name";</p>
<p>
btnEnterName.Click += btnEnterName_Click;</p>
<p>
//</p>
<p>
// lblGreeting</p>
<p>
//</p>
<p>
lblGreeting.Location = new Point(24, 56);</p>
<p>
lblGreeting.Name = "lblGreeting";</p>
<p>
lblGreeting.Size = new Size(248, 24);</p>
<p>
lblGreeting.Text = "Welcome!";</p>
<p>
//</p>
<p>
// cboFavoriteColor</p>
<p>
//</p>
<p>
cboFavoriteColor.Items.AddRange(new object[] { "Red", "Green", "Blue", "Yellow" });</p>
<p>
cboFavoriteColor.Location = new Point(24, 90);</p>
<p>
cboFavoriteColor.Name = "cboFavoriteColor";</p>
<p>
cboFavoriteColor.Size = new Size(240, 21);</p>
<p>
//</p>
<p>
// Form1</p>
<p>
//</p>
<p>
AutoScaleDimensions = new SizeF(6F, 13F);</p>
<p>
AutoScaleMode = AutoScaleMode.Font;</p>
<p>
ClientSize = new Size(292, 181);</p>
<p>
Controls.AddRange(new Control[] { cboFavoriteColor, lblGreeting, btnEnterName });</p>
<p>
Name = "Form1";</p>
<p>
Text = "Main Window";</p>
<p>
Load += Form1_Load;</p>
<p>
}</p>
<p>}</p>
Form2.cs
using System;</p>
<p>namespace TestApp</p>
<p>{</p>
<p>
public partial class Form2 : Form</p>
<p>
{</p>
<p>
public Form1 MyParentForm;</p>
<p>
public string UserName => txtName.Text;</p>
<p>
public Form2()</p>
<p>
{</p>
<p>
}</p>
<p>
private void btnOk_Click(object sender, EventArgs e)</p>
<p>
{</p>
<p>
Close();</p>
<p>
}</p>
<p>
private void btnCancel_Click(object sender, EventArgs e)</p>
<p>
{</p>
<p>
Close();</p>
<p>
}</p>
<p>
private void Form2_Load(object sender, EventArgs e)</p>
<p>
{</p>
<p>
if (MyParentForm?.cboFavoriteColor.SelectedItem is string colorName)</p>
<p>
BackColor = Color.FromName(colorName);</p>
<p>
}</p>
<p>
}</p>
<p>}</p>
Form2.Designer.cs
partial class Form2</p>
<p>{</p>
<p>
private TextBox txtName;</p>
<p>
private Button btnOk;</p>
<p>
private Button btnCancel;</p>
<p>
{</p>
<p>
txtName = new TextBox();</p>
<p>
btnOk = new Button();</p>
<p>
btnCancel = new Button();</p>
<p>
//</p>
<p>
// txtName</p>
<p>
//</p>
<p>
txtName.Location = new Point(16, 32);</p>
<p>
txtName.Name = "txtName";</p>
<p>
txtName.Size = new Size(264, 20);</p>
<p>
txtName.Text = "Please enter your name";</p>
<p>
//</p>
<p>
// btnOk</p>
<p>
//</p>
<p>
btnOk.DialogResult = DialogResult.OK;</p>
<p>
btnOk.Location = new Point(16, 80);</p>
<p>
btnOk.Name = "btnOk";</p>
<p>
btnOk.Size = new Size(88, 40);</p>
<p>
btnOk.Text = "OK";</p>
<p>
btnOk.Click += btnOk_Click;</p>
<p>
//</p>
<p>
// btnCancel</p>
<p>
//</p>
<p>
btnCancel.DialogResult = DialogResult.Cancel;</p>
<p>
btnCancel.Location = new Point(152, 80);</p>
<p>
btnCancel.Name = "btnCancel";</p>
<p>
btnCancel.Size = new Size(80, 40);</p>
<p>
btnCancel.Text = "Cancel";</p>
<p>
btnCancel.Click += btnCancel_Click;</p>
<p>
//</p>
<p>
// Form2</p>
<p>
//</p>
<p>
ClientSize = new Size(292, 149);</p>
<p>
Controls.AddRange(new Control[] { txtName, btnOk, btnCancel });</p>
<p>
Name = "Form2";</p>
<p>
Text = "Enter Your Name";</p>
<p>
Load += Form2_Load;</p>
<p>
}</p>
<p>}</p>
These snippets cover the essentials of a parent dialog interaction: the main form holds the data source (the selected color), the dialog reads that source on load, the dialog writes back a value (the name), and the main form reacts to the result. In production code, you might replace the public field with a constructor that takes a reference to the parent form or use data binding for more complex scenarios. You could also employ event callbacks instead of polling DialogResult, especially if the dialog can be closed by other means such as the window close button.
If you’re interested in learning more about modal dialogs, Microsoft’s documentation on ShowDialog offers deeper insight into its behavior, thread safety considerations, and custom result values. Experiment with adding validation logic, handling the FormClosing event, or integrating themes to broaden the user experience. The pattern illustrated here scales well to larger projects: each dialog remains a self‑contained unit that communicates with its caller through well‑defined interfaces, keeping your code modular and maintainable.





No comments yet. Be the first to comment!