【问题标题】:Read certain information from a file relating to datetime chosen in DateTimePicker从与 DateTimePicker 中选择的日期时间相关的文件中读取某些信息
【发布时间】:2021-04-16 12:01:27
【问题描述】:

我有一个文件,其中包含我正在读取的天气信息并将其放入一个结构中,然后我将其添加到列表中。我有一个 dateTimePicker 控件,用户将使用它来选择一月份的日期,当他们这样做时,我需要它打印到 listBox 控件我存储在列表中的那天的日期和天气信息.我已经将文件标记化并放入结构变量并将其添加到列表中。

当我通过 dateTimePicker 控件选择一个日期时,我最终会一次获得所有日期和信息。我相信因为我不明白如何使用 dateTimePicker 控件,所以我无法弄清楚。

所以,当我选择 2018 年 1 月 1 日时,我需要它在 listBox 中引入当天的日期和降水、高温、低温等天气信息。我希望我已经将所有内容解释得足够清楚,以便您理解。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace Chapter9_Problem1_
{
    public partial class Form1 : Form
    {
        // create new structure
        struct Weather
        {
            public string date;
            public string precipitation;
            public string highTemp;
            public string lowTemp;
        }
        // create new list
        private List<Weather> weatherList = new List<Weather>();

        // method to get info from file and store into list 
        private void fileData()
        {
            StreamReader inputFile;
            inputFile = File.OpenText("weather.txt");

            while(!inputFile.EndOfStream)
            {
                // create instance of the weather structure
                Weather weather = new Weather();
                // read the file and store into info variable
                string info = inputFile.ReadLine();
                // create char array for delimiter
                char[] delimiter = { ';' };
                // split info by each delimiter
                string[] tokens = info.Split(delimiter);

                // store the values into the structure weather variables
                weather.date = tokens[0];
                weather.precipitation = tokens[1];
                weather.highTemp = tokens[2];
                weather.lowTemp = tokens[3];
                // add to the list
                weatherList.Add(weather);
                    
                
            }
            
        }
       

        public Form1()
        {
            InitializeComponent();
        }

        // dateTimePicker method
        private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
        {
            // call file data method
            fileData();

            // create datetime object
            DateTime dateTime = new DateTime();
            // assign datetime object to the datetimepicker control
            dateTime = dateTimePicker1.Value;
            foreach(Weather weather in weatherList)
            {
                listBox1.Items.Add(weather.date + weather.date + weather.highTemp + weather.lowTemp);
            }
            

        }

        
    }
}

【问题讨论】:

  • 此处允许使用仅供参考的段落 :)
  • 我在您的代码中没有看到您实际使用日期选择器值的任何地方。当然你将它分配给一个变量 (dateTime = dateTimePicker1.Value;) ,但你实际上并没有将它用于任何事情。
  • 我的建议:将文件中的日期解析为Weather 模型中的DateTime。完成后,您可以根据 weather.date.Date == dateTime.Date 过滤 weatherList
  • 文件中每一行的日期是否总是相同的格式?您能否提供文件中的日期样本?
  • 你能告诉我格式吗?也许只是提供文件中的示例日期/时间值?在不知道格式的情况下,我无法编写代码来解析日期。

标签: c# winforms datetimepicker


【解决方案1】:

我会将您的模型更改为使用DateTime 而不是string 作为日期:

struct Weather
{
    public DateTime date;
    public string precipitation;
    public string highTemp;
    public string lowTemp;
}

像这样改变你的阅读代码:

string[] tokens = info.Split(delimiter);

// try to parse the date
if (!DateTime.TryParseExact(tokens[0], "M/d/yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out var date))
{
    MessageBox.Show($"The file contains an invalid date: tokens[0].");
    return;
}
// store the values into the structure weather variables
weather.date = date;
weather.precipitation = tokens[1];
weather.highTemp = tokens[2];
weather.lowTemp = tokens[3];
// add to the list
weatherList.Add(weather);

最后,将 dateTimePicker1_ValueChanged 中的代码更改为:

foreach(Weather weather in weatherList.Where(w => w.date.Date == dateTime.Date))
{
    string dateAsString = weather.date.ToString("M/d/yyyy", CultureInfo.InvariantCulture);
    listBox1.Items.Add(dateAsString + weather.highTemp + weather.lowTemp);
}

Documentation for TryParseExact:

使用指定的格式、特定于区域性的格式信息和样式,将日期和时间的指定字符串表示形式转换为其等效的 DateTime。字符串表示的格式必须与指定的格式完全匹配。该方法返回一个值,指示转换是否成功。

Documentation for DateTime's ToString method:

使用指定的格式和特定​​于区域性的格式信息将当前 DateTime 对象的值转换为其等效的字符串表示形式。

我还建议阅读 Microsoft 的 C# coding conventions 并在一定程度上关注它们,因为遵循共同的开发风格可以让其他人更容易阅读和维护您的代码。

附:请注意,每次您的日期选择器值更改时,您都会调用fileData(),并且fileData() 在填充列表之前不会清除列表。你最终会得到这样的重复值。我建议在填写之前清除列表,或者将调用 fileData() 转移到表单加载事件。

【讨论】:

  • 大声笑我很抱歉,但你正在使用我以前从未见过的东西。我试过了,我猜我需要为 CultureInfo 包含一个库
  • @Fitzgerald 啊,你需要在代码文件的顶部添加using System.Globalization;。请注意,如果您右键单击CultureInfo,重构菜单中应该有一个选项来包含它的使用(我假设您使用的是 Visual Studio)。
  • 向 PascalCase 推荐结构的公共成员 - 不妨尽早让他们开始使用正确的 C# 约定!
  • @Fitzgerald 当 llama 说“重构菜单”时,它们的意思是“指向/单击下面带有摆动红线的单词,当 ? 出现在单词附近或边缘时,单击并选择通过“添加“使用 System.Globalization”或类似措辞来修复它的选项。还有另一个“完全限定”选项,它可以工作,但往往会使代码更混乱——我只如果我知道我只会在一个文件中执行一次,或者如果三个是阻止使用 using 的命名冲突,请执行此操作
  • 在调试器中单步调试代码以找出其工作原理。这本质上是一个明智的概念,即获取文本数据并使用 (日期时间)的数据类型而不是更难处理的文本(你不能减去 10只是恰好看起来像日期时间的字符串)
猜你喜欢
  • 2010-09-10
  • 2014-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-05
  • 2023-03-11
  • 1970-01-01
相关资源
最近更新 更多