C # Windows Forms Application: Separate GUI from Business Logic

I would like to get some tips on how to separate the interface and business logic from a simple C # application for Windows Forms.

Take this example:

The user interface consists of a simple text field and a button. The user enters a number from 0 to 9 and presses the button. The program should add 10 to the number and update the text box with this value.

enter image description here

Part of the business logic should not have an understanding of the user interface. How can I do that?

Here's the empty Process class (Business Logic):

namespace addTen { class Process { public int AddTen(int num) { return num + 10; } } } 

Demand:

  • When the user clicks the button, the :: AddTen process is called somehow.
  • The text field should be updated with the return value of Process :: AddTen.

I just don’t know how to connect these two.

+9
user-interface c # events business-logic
source share
4 answers

First, you need to change the name of your class. " Process " is the name of the class in the class library and is likely to cause confusion for anyone reading your code.

Suppose for the rest of this answer you changed the class name to MyProcessor (still a bad name, but not a well-known, commonly used class.)

In addition, you do not have enough code to verify that user input is indeed a number from 0 to 9. This is necessary in the form code, and not in the class code.

  • Assuming TextBox is named textBox1 (VS is generated by default for the first TextBox added to the form)
  • Further, provided that the name of the button is button1

In Visual Studio, double-click the button to create a button click event handler that looks like this:

 protected void button1_Click(object sender, EventArgs e) { } 

Inside the event handler, add code so that it looks like this:

  protected void button1_Click(object sender, EventArgs e) { int safelyConvertedValue = -1; if(!System.Int32.TryParse(textBox1.Text, out safelyConvertedValue)) { // The input is not a valid Integer value at all. MessageBox.Show("You need to enter a number between 1 an 9"); // Abort processing. return; } // If you made it this far, the TryParse function should have set the value of the // the variable named safelyConvertedValue to the value entered in the TextBox. // However, it may still be out of the allowable range of 0-9) if(safelyConvertedValue < 0 || safelyConvertedValue > 9) { // The input is not within the specified range. MessageBox.Show("You need to enter a number between 1 an 9"); // Abort processing. return; } MyProcessor p = new MyProcessor(); textBox1.Text = p.AddTen(safelyConvertedValue).ToString(); } 

A class with an established access rule should look like this:

 namespace addTen { public class MyProcessor { public int AddTen(int num) { return num + 10; } } } 
+6
source share

Make your "Process" class public (and as @DavidStratton says, change the name):

 public class MyProcess 

I would say that you should TextBox.Text string value from TextBox.Text to int :

 private void button1_Click(object sender, EventArgs e) { MyProcess myProcess = new MyProcess(); string result = textBox1.Text; int number; if(int.TryParse(textBox1.Text, out number)) { result = myProcess.AddTen(number).ToString(); } textBox1.Text = result; } 
+2
source share

For example, you can create another class called "Process.cs". Methods that include processing or calculating the data that you move there. For example, in your case:

 public class Process { public int AddTen(int num) { return num + 10; } } 

Your UI click event will have a call to your "process level":

  var myProcess = new Process(); //and then calculation var initNumber = Convert.ToInt32(textBox.Text); var calculatedValue = myProcess.AddTen(initNumber); textBox.Text = calculatedValue.ToString(); 

Thus, your business logic, such as computing, is stored separately. If your user interface changes, you can still just call the myProcess.AddTen () method, whether it's a website, Windows, or a mobile form.

+2
source share

To completely separate the logic, you can declare a base class that can contain a button and control handlers. Your particular process can inherit a base class, and logic can be set. Finally, the form can declare an instance of the class and pass the button.

It looks something like this:

 class BaseProcessor { System.Windows.Forms.Button myButton; public System.Windows.Forms.Button MyButton { get { return myButton; } set { myButton = value; myButton.Click += new System.EventHandler(this.MyButton_Click); } } public BaseProcessor() { } public virtual void MyButton_Click(object sender, EventArgs e) { } 

Then declare the process:

 class MyProcess : BaseProcessor { public override void MyButton_Click(object sender, EventArgs e) { MessageBox.Show("This is my process"); } } 

Then, inside the form, declare an instance of the process and attach the button:

 public partial class Form1 : Form { MyProcess myProcess = null; public Form1() { InitializeComponent(); myProcess = new MyProcess { MyButton = button1 }; } } 

When using this method, the business logic code is missing in the form. The parent class is useful because events such as button presses are quite common, so in my opinion it is easier to declare them centrally.

0
source share

All Articles