C#Windows窗体应用程序:从业务逻辑中分离GUI

时间:2012-07-18 17:54:46

标签: c# events user-interface business-logic

我想就如何在简单的C#Windows窗体应用程序中分离UI和业务逻辑提出一些建议。

我们来看这个例子:

UI包含一个简单的文本框和一个按钮。用户输入0到9之间的数字并单击该按钮。程序应该在数字上加10,并用该值更新文本框。

enter image description here

业务逻辑部分应该不知道UI。如何实现这一目标?

这是空的Process类(业务逻辑):

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

要求是:

  1. 当用户点击按钮时,会以某种方式调用Process :: AddTen。
  2. 必须使用Process :: AddTen的返回值更新文本框。
  3. 我只是不知道如何连接这两个。

4 个答案:

答案 0 :(得分:6)

首先,您需要更改您的班级名称。 “进程”是类库中类的名称,可能会让读取代码的任何人感到困惑。

我们假设,对于本答案的其余部分,您将类名更改为 MyProcessor (仍然是一个错误的名称,但不是一个众所周知的常用类。)

此外,您缺少要检查的代码,以确保用户输入确实是0到9之间的数字。这在Form的代码而不是类代码中是合适的。

  • 假设TextBox名为textBox1(VS为第一个添加到表单的TextBox生成默认值)
  • 进一步假设按钮的名称为button1

在Visual Studio中,双击按钮以创建按钮单击事件处理程序,如下所示:

protected void button1_Click(object sender, EventArgs e)
{

}

在事件处理程序中,添加代码使其如下所示:

 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();
 }

正确设置了访问修饰符的类应该如下所示:

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

答案 1 :(得分:2)

制作您的&#39;流程&#39; class public(以及@DavidStratton说,更改名称):

public class MyProcess

我会说你应该将string的{​​{1}}值解析为TextBox.Text

int

答案 2 :(得分:2)

例如,您可以创建另一个名为“Process.cs”的类。 涉及处理或数据计算的方法。例如:

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

您的UI点击事件将调用您的“处理层”:

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

  textBox.Text = calculatedValue.ToString();

这样,您的业务逻辑(例如计算)将单独保存。如果您的UI发生了变化,您仍然可以简单地调用myProcess.AddTen()方法,无论它是Web,Windows还是Mobile表单。

答案 3 :(得分:0)

要完全分离逻辑,可以声明一个可以包含按钮和管理处理程序的基类。您的特定过程可以继承基类,并且可以设置逻辑。最终,表单可以声明该类的实例并传递按钮。

它看起来像这样:

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)
    {
    }

然后声明该过程:

class MyProcess : BaseProcessor
{

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

然后在表单内部,声明流程的实例并附加按钮:

public partial class Form1 : Form
{

    MyProcess myProcess = null;

    public Form1()
    {
        InitializeComponent();

        myProcess = new MyProcess
        {
            MyButton = button1
        };
    }

}

使用此方法,表单中没有业务逻辑代码。父类非常有用,因为单击按钮之类的事件非常普遍,因此我认为更容易集中声明它们。