Winforms 我该怎么清理?

Winforms 我该怎么清理?,winforms,c#-4.0,Winforms,C# 4.0,我正在使用一个利用Google Weather API的应用程序,现在我得到了一些非常难看的代码来填充3天的天气预报,看起来是这样的(记住不要笑) 我告诉过你这很难看。我想做的是使用一个循环(和可能的泛型)来完成与这段丑陋代码相同的任务。我试过几种不同的方法,但总是失败。天气就是这样产生的 WeatherSet set = WeatherService.Response(GoogleWeatherRequest.RequestData(new WeatherService("99109")));

我正在使用一个利用Google Weather API的应用程序,现在我得到了一些非常难看的代码来填充3天的天气预报,看起来是这样的(记住不要笑)

我告诉过你这很难看。我想做的是使用一个循环(和可能的泛型)来完成与这段丑陋代码相同的任务。我试过几种不同的方法,但总是失败。天气就是这样产生的

WeatherSet set = WeatherService.Response(GoogleWeatherRequest.RequestData(new WeatherService("99109")));

在变量集合中有当前信息和3天预测的信息,但这样运行会让我发疯,因为它太无趣,效率也不高。那么,有人找到了完成这项任务的酷而有效的方法吗?

您的代码没有任何低效之处。重复自己的话有点让人难过,但这并没有什么真正的问题

如果要避免重复,只需将控件放入数组中,即可执行以下操作:

for (index in number of forecasts) {
   groupBox[index].Text = set.Forecast[index]....;
   hiLabel[index].Text  = ...:
   lowLabel[index].Text = ...:
   ...
}

你的代码没有低效的地方。重复自己的话有点让人难过,但这并没有什么真正的问题

如果要避免重复,只需将控件放入数组中,即可执行以下操作:

for (index in number of forecasts) {
   groupBox[index].Text = set.Forecast[index]....;
   hiLabel[index].Text  = ...:
   lowLabel[index].Text = ...:
   ...
}

您是否尝试过对控件进行分组或动态生成控件?这样,您就不必索引到Forecast列表中,您只需枚举集合,而不是为每个迭代使用不同的控件,您只需要填充单个集合

foreach (var item in set.Forecast.Take(3))
{
    var groupBox = new GroupBox(); // it don't if the class is actually called GroupBox...
    groupBox.Text = item.DayOfTheWeek;
    labelHigh.Text = string.Format("High {0}", item.High);
    labelLow.Text = string.Format("Low: {0}", item.Low);
    labelCondition.Text = string.Format("Condition: {0}", item.Condition);
    pictureBox.Load(item.Icon);
    groupBox.Controls.Add(labelHigh)
    ...
    this.Controls.Add(groupBox);
}
上面的代码只是给你一个想法


实际上,你的代码没有太多问题,我唯一真正缺少的是一个断言,即你的索引没有超出范围。

你有没有尝试过对控件进行分组或动态创建控件?这样,您就不必索引到Forecast列表中,您只需枚举集合,而不是为每个迭代使用不同的控件,您只需要填充单个集合

foreach (var item in set.Forecast.Take(3))
{
    var groupBox = new GroupBox(); // it don't if the class is actually called GroupBox...
    groupBox.Text = item.DayOfTheWeek;
    labelHigh.Text = string.Format("High {0}", item.High);
    labelLow.Text = string.Format("Low: {0}", item.Low);
    labelCondition.Text = string.Format("Condition: {0}", item.Condition);
    pictureBox.Load(item.Icon);
    groupBox.Controls.Add(labelHigh)
    ...
    this.Controls.Add(groupBox);
}
上面的代码只是给你一个想法


实际上,你的代码没有太多问题,我唯一真正缺少的是一个断言,你的索引没有超出范围。

我认为你应该为它创建自己的自定义控件ForecastView,上面有groupbox、三个标签和picturebox。让它有一个名为
Forecast
的属性,并将填充字段的逻辑放入其setter中。这样表单的代码就会非常干净,比如

forecastView1.ForeCast = set.Forecast[1];
forecastView2.ForeCast = set.Forecast[2];
// etc
鉴于您已经将字段放在groupbox中,放置应该不会有问题


此外,如果有一天您需要在另一个表单甚至另一个应用程序中显示这些数据,那么将这些数据放在单独的控件中将为您提供许多代码重用选项。更不用说,如果您决定将pictureBox放在左侧而不是右侧,您将能够立即更改所有预测的外观。等等。

我认为您应该使用groupbox、三个标签和pictureBox为其创建自己的自定义控件ForecastView。让它有一个名为
Forecast
的属性,并将填充字段的逻辑放入其setter中。这样表单的代码就会非常干净,比如

forecastView1.ForeCast = set.Forecast[1];
forecastView2.ForeCast = set.Forecast[2];
// etc
鉴于您已经将字段放在groupbox中,放置应该不会有问题


此外,如果有一天您需要在另一个表单甚至另一个应用程序中显示这些数据,那么将这些数据放在单独的控件中将为您提供许多代码重用选项。更不用说,如果您决定将图片盒放在左侧而不是右侧,您将能够立即更改所有预测的外观,等等。

这是我最后使用的解决方案(感谢@dyppl)。对于用户控制的想法

public partial class forecastView : UserControl
{    
    public forecastView()
    {
        InitializeComponent();
    }

    public forecastView(int x, int y, int index,WeatherSet set)
    {
        InitializeComponent();

        label7.Text = string.Format("High:{0}", set.Forecast[index].High);
        label8.Text = string.Format("Low: {0}", set.Forecast[index].Low);
        pictureBox3.Load(string.Format("http://www.google.com/{0}", set.Forecast[index].Icon));
        groupBox1.Text = set.Forecast[index].DayOfTheWeek;

        this.Location = new System.Drawing.Point(x, y);
    }
}
我是这样装的

private void LoadControls(WeatherSet set)
{
    RemoveConrols();
    //form2.Dispose();

    form = new forecastView(12, 136, 1, set);
    form1 = new forecastView(155, 136, 2, set);
    form2 = new forecastView(12, 218, 3, set);

    this.Controls.Add(form);
    this.Controls.Add(form1);
    this.Controls.Add(form2);
}

因此,感谢所有帮助我解决这个问题的人;)

这就是我最后提到的解决方案(谢谢@dyppl)。对于用户控制的想法

public partial class forecastView : UserControl
{    
    public forecastView()
    {
        InitializeComponent();
    }

    public forecastView(int x, int y, int index,WeatherSet set)
    {
        InitializeComponent();

        label7.Text = string.Format("High:{0}", set.Forecast[index].High);
        label8.Text = string.Format("Low: {0}", set.Forecast[index].Low);
        pictureBox3.Load(string.Format("http://www.google.com/{0}", set.Forecast[index].Icon));
        groupBox1.Text = set.Forecast[index].DayOfTheWeek;

        this.Location = new System.Drawing.Point(x, y);
    }
}
我是这样装的

private void LoadControls(WeatherSet set)
{
    RemoveConrols();
    //form2.Dispose();

    form = new forecastView(12, 136, 1, set);
    form1 = new forecastView(155, 136, 2, set);
    form2 = new forecastView(12, 218, 3, set);

    this.Controls.Add(form);
    this.Controls.Add(form1);
    this.Controls.Add(form2);
}

因此,感谢所有帮助我解决这个问题的人;)

您必须通过代码来实现这一点。除非您将控件移动到用户控件中,否则该用户控件将充当您的分组,您只需创建该控件的实例并设置该用户控件的属性。您必须通过代码来完成此操作。除非您将控件移动到用户控件中,否则用户控件将充当您的分组,您只需创建该控件的实例并设置该用户控件的属性。我了解您尝试如何使用此想法,但在实现它时遇到了一些问题。不知何故,我必须将数据输入UC,以便填充UC中的项目。我希望这个问题有道理;)@心理编码员:像我建议的那样在你的UC课程中添加一个
Forecast
类型的属性有什么不对?因为我只知道当前的天气,让我们看看我能想出什么。我爱这个世界idea@PsychoCoder:我的意思是,您必须放置此控件的三个实例来显示3个不同的预测。我了解您试图使用此想法做什么,但在实现时遇到一些问题。不知何故,我必须将数据输入UC,以便填充UC中的项目。我希望这个问题有道理;)@心理编码员:像我建议的那样在你的UC课程中添加一个
Forecast
类型的属性有什么不对?因为我只知道当前的天气,让我们看看我能想出什么。我爱这个世界idea@PsychoCoder:我的意思是,您必须放置此控件的三个实例才能显示3种不同的预测