如何让Windows窗体应用程序与类一起使用?

时间:2011-11-14 07:56:20

标签: c# winforms class

我是初学者在C#中学习Windows Forms应用程序,我想编写一个程序,提示用户输入一个地方的名称,并输入20到100之间的2位数温度(F)。用户按下表格上的“确定”按钮我希望有一个消息框,显示他们输入的地方的名称,以及他们输入的温度(F)加上其摄氏温度转换以及如果任何字段留空的错误消息或者如果温度超出范围。

我想有一个类来处理转换和逻辑。

我还在学习各种各样的人,而且我已经花了一整天才完成这项工作已经只有几段代码正在运行,但我担心我不理解我在做什么。我对表单设计没问题,我遇到的问题是c#代码和使用类。如果有人可以向我展示我想要做的代码或提示,我真的很感激。

为了你的缘故,我不包括我的代码,因为它可能会让你感到困惑,然后我们会花几个小时谈论“我为什么要做某事”,但如果你真的想看到它让我知道。

作为初学者,我非常欣赏初学者般的答案。 谢谢你们!

// Form1.cs

using System.Linq;
using System.Text;
using System.Windows.Forms;

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

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void label2_Click(object sender, EventArgs e)
        {

        }

        private void label3_Click(object sender, EventArgs e)
        {

        }

        private void btn_quit_Click(object sender, EventArgs e)
        {
            base.Close();
            return;
        }

        public void btn_record_Click(object sender, EventArgs e)
        {
            string place;
            place = Console.ReadLine();
            Calculations name = new Calculations();
            //double temp = Convert.ToDouble(txtTemperature.Text);
            //Calculation ctemp = new Calculation();


        MessageBox.Show(name.GetPlaceName("Calculations: " + txtPlaceName.Text));
        //MessageBox.Show(string.Format("Temperature: {0}", (ctemp.GetTemp(celsiusTemp.text))));


}


//Class


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Calculations
{
    class Calculations
    {


        string placeName;
        double celsiusTemp;

        public string GetPlaceName(string place)        
{

                return placeName = place;            
        }

    public double GetTemp(double temp)
        {
            return celsiusTemp = (temp + 10); 
        }

    }
}

2 个答案:

答案 0 :(得分:8)

您需要做的是退后一步,忽略整个WinForms问题。首先尝试解决具体问题:

  

我想编写一个程序,提示用户输入一个地方的名称,并输入20到100之间的2位数温度(F)。当用户按下我想要的表格上的“确定”按钮时有一个消息框显示他们输入的地方的名称,以及他们输入的温度(F)加上其摄氏温度转换和错误消息,以防任何字段留空或者温度超出范围。

可以分解为两个不同的问题:

  1. 输入温度值介于20到99之间(因为您指定了两位数字)
  2. 将温度转换为摄氏度
  3. 验证总是应该完成的,所以我不认为它是一个单独的问题。

    接下来要做的是考虑您希望解决方案如何工作。始终从解决方案开始,因为它通常比直接创建实现更容易。测试驱动开发真的很棒,因为它确实如此。

    我想要这样的东西(伪代码):

    var fahrenheit = dialog.GetInput();
    var celcius = fahrenheit.Convert(new FahrenheitToCelciusConverter());
    resultDialog.Show(fahrenheit, celsius);
    

    定义对象

    既然我们知道自己想做什么,那就让我们更多地关注实际的实施。通过查看伪代码,我们发现我们需要几个类。

    首先,我们需要获得输入

    // the validation should be done in this form when the user 
    // presses OK. But that's up to you to figure out
    public class PlaceAndTemperatureForm : Form
    {
        public PlaceAndTemperature GetPlaceAndTemperature()
        {
            return new PlaceAndTemperature(txtName.Text, int.Parse(txtTemperature .Text));
        }
    }
    

    由于我们需要从表单中获取数据,因此我们创建一个包含它的类:

    public class PlaceAndTemperature 
    {
         public PlaceAndTemperature(string name, int temperature)
         {
             Name = name;
             Temperature = temperature;
         }
         public string Name { get; private set; } 
         public int Temperature { get; private set; } 
    
    }
    

    看看上面的课程。它有私有的setter,这意味着没有其他类或代码可以修改它。它被称为不可变对象。好消息是我们知道使用它总是安全的,并且不能处于意外/无效状态。您应该总是尝试使用不可变对象,或者至少不让任何其他对象更改状态而不让类本身验证更改。

    接下来是转换。我们写了以下代码:

    var celcius = placeAndTempature.Convert(new FahrenheitToCelciusConverter());
    

    因此我们需要修改类以获取转换器并返回一个新位置。

    public class PlaceAndTemperature 
    {
         public PlaceAndTempature(string name, int temperature)
         {
             Name = name;
             Temperature = temperature;
         }
         public string Name { get; private set; } 
         public int Temperature { get; private set; } 
    
         public PlaceAndTemperature Convert(ITemperatureConverter converter)
         {
             return new PlaceAndTemperature(Name, converter.Convert(Temperature));
         }
    }
    

    我刚刚介绍了一个名为Interfaces的新概念。您可以将它们视为文字模板或蓝图。它们用于定义类的外观,但不具有任何逻辑。这是一个规范。

    public interface ITemperatureConverter 
    {
        int Convert(int source);
    }
    

    现在的问题是我们有两个PlaceAndTemperature对象,原始对象是华氏度,另一个是celcius。我们需要能够确定使用哪种单位,否则我们最终可能会遇到一些令人讨厌的错误。

    让我们使用enum添加单位规范。

    public enum TempatureUnit
    {
        Celcius,
        Fahrenheit
    }
    

    修改以前的类和接口:

    public interface ITemperatureConverter 
    {
        int Convert(int source);
        TempatureUnit SourceUnit {get;}
        TempatureUnit TargetUnit {get;}
    }
    
    public class PlaceAndTemperature 
    {
         public PlaceAndTempature(string name, int temperature, TempatureUnit unit)
         {
             Name = name;
             Temperature = temperature;
             TempatureType = unit;
         }
         public string Name { get; private set; } 
         public int Temperature { get; private set; } 
         public TempatureUnit TemperatureType {get; private set; }
         public PlaceAndTemperature Convert(ITemperatureConverter converter)
         {
             return new PlaceAndTemperature(Name, converter.Convert(Temperature), converter.TargetUnit);
         }
    }
    

    全部放在一起

    大。现在不多了。让我们重新审视原始代码并进行更新:

    public void Button1_Click(object source, EventArgs e)
    {
        var form = new PlaceAndTemptureForm();
        var result = form.ShowDialog(this);
        if (result != DialogResult.Ok)
            return; // failed for some reason
    
        var fahrenheit = form.GetPlaceAndTemperature();
    
        var celcius = fahrenheit .Convert(new FahrenheitToCelciusConverter());
    
        var form = new ResultForm();
        form.SetTemperatures(fahrenheit, celsius);
        resultDialog.ShowDialog(this);
    }
    

    <强>摘要

    还有一些事情你需要自己解决。就像创建FahrenheitToCelciusConverter一样。从以下内容开始:

    public class FahrenheitToCelciusConverter : ITemperatureConverter
    {
        public int Convert(int source)
        {
             // put your code here
        }
        public TempatureUnit SourceUnit {get { return TemperatureUnit.Fahrenheit; }}
        public TempatureUnit TargetUnit {get { return TemperatureUnit.Celcius; }}
    }
    

    您还需要创建结果表单,或者只是更新主表单。

答案 1 :(得分:1)

  

此时在Form1.cs中我得到“'celciusTemp'在当前上下文中不存在”

行;现在我们到了某个地方。 celciusTemp确实是Calculations的一部分,而不是Form1,但这不应该影响我们,因为我们已经有了温度:

double temp = Convert.ToDouble(txtTemperature.Text);

(我假设txtTemperature存在)

问题似乎是在后面的调用中没有使用temp

MessageBox.Show(string.Format("Temperature: {0}", ctemp.GetTemp(temp)));

(请注意,上面的内容使用的是temp,而不是celsiusTemp

作为旁白,我不确定是否有必要将placeNamecelsiusTemp存储为Calculations类的字段;它们可以是静态方法,除非有更多细节要添加。但这与主要问题无关。