【问题标题】:C# Windows Form search txt file for passed data and pass to textboxesC# Windows 窗体搜索 txt 文件以获取传递的数据并传递到文本框
【发布时间】:2016-03-04 19:42:49
【问题描述】:

我对 C# 比较陌生,并且花了很多时间试图自己解决这个问题,但没有运气。希望大家帮忙。

我有 2 个窗体。在第一种形式中,用户输入引文编号。我想获取该引用编号,在外部文本文件中搜索它,然后将该引用的行中的所有数据返回到单独的文本框中。

文本文件如下所示:

S8729936 , 6JXV123 , 10/1/2015 , 10/31/2015 , PAID , 49.5
A7472601 , 2NXP234 , 10/12/2015 , 11/11/2015 , UNPAID , 99
W2041810 , 5JPB345 , 10/19/2015 , 11/18/2015 , UNPAID , 99

第二种形式有6个文本框。我有它,所以引用号,假设 S8729936 被传递到第一个文本框,但我似乎无法弄清楚如何在文本文件中搜索 S8729936 并给我文本框内行中的其余数据。

以下是我尝试过的一些示例。我整天都在复制和粘贴,然后弄乱代码,所以如果细节似乎不匹配,那可能就是原因。

public Form2(string citation)
    {
        InitializeComponent();
        txtCitation2.Text = citation;

        const string FILENAME = @"\Path\ProjectData.txt";
        FileStream fsInFile = new FileStream(FILENAME, FileMode.Open, FileAccess.Read);
        StreamReader srReader = new StreamReader(fsInFile);

        const char CH_DELIM = ',';
        string strRecordIn;
        string[] strFields;

        if (strFields != null)
        {
            strRecordIn = srReader.ReadLine();
            strFields = strRecordIn.Split(CH_DELIM);
            txtLicense2.Text = strFields[1];
        }
strRecordIn = srReader.ReadLine();

        srReader.Close();
        fsInFile.Close();
    }

没有运气,像这样的事情怎么样:

string whole_file = File.ReadAllText(@"Path\ProjectData.txt");
        whole_file = whole_file.Replace('\n', '\r');
        string[] lines = whole_file.Split(new char[] { '\r' });

        int num_rows = lines.Length;
        int num_cols = lines[0].Split(',').Length;

        string[,] values = new string[num_rows, num_cols];

        for (int r = 0; r < num_rows; r++)
        {
            string[] line_r = lines[r].Split(',');
            for (int c = 0; c < num_cols; c++)
            {
                values[r, c] = line_r[c];
            }
        }

        txtLicense2.Text = lines[1];

不。也许是这样的:

const string FILENAME = @"C:\Users\rfranklin\Documents\ProjectData.txt";
        FileStream fsinfile = new FileStream(FILENAME, FileMode.Open, FileAccess.Read);
        StreamReader srReader = new StreamReader(fsinfile);

        const string CH_DELIM = " ,";
        string strRecordIn;
        string[] strFields = new string[10];
        string citnum = citation;
        bool found = false;

        strRecordIn = srReader.ReadLine();

        foreach(string x in strFields)
        {
            if (x == citation)
            {
                found = true;
                break;
            }
        }

        if (found)
        {
            txtLicense2.Text = strFields[1];
        }

仍然没有运气。不断地。似乎我主要是想念如何告诉程序要搜索什么,我不知道还能做什么。就像我说的那样,我整天都在谷歌上搜索各种方法来做这件事,但我似乎无法让任何事情正常工作。

如果有帮助,我正在 Visual Studio 2013 中执行此操作。

任何帮助将不胜感激。谢谢。

【问题讨论】:

  • 你需要循环文件内容。您只是在阅读第一行并对其进行处理。您需要将 ReadLine() 放入循环中。
  • 你的文件有多少行?您是否可以控制此文件的格式,还是以 CSV 格式提供给您?是否有可能将其转换为数据库表(Access、MS SQL 等)?

标签: c# arrays winforms multidimensional-array


【解决方案1】:

@interceptwind 的建议帮了我。在他提供的代码的 //output 部分中,我基本上只是从匹配的行中创建了第二个数组,元素用逗号分隔。代码如下所示:

        //output
        foreach (string s in matchedList)
        {
            string citationLine = s;
            string[] lineData = citationLine.Split(',');
            txtLicense2.Text = lineData[1];
            txtIssued2.Text = lineData[2];
            txtDue2.Text = lineData[3];
            txtStatus2.Text = lineData[4];
            txtAmount2.Text = lineData[5];
        }

这使我可以将数据放入所需的文本框中。谢谢大家的帮助!

【讨论】:

    【解决方案2】:

    一个简单的winForm版本:

    using System;
    using System.Collections.Generic;
    using System.Windows.Forms;
    using System.IO;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            List<string> matchedList = new List<string>();
    
            public Form1(string citation)
            {
                InitializeComponent();
    
                string filePath = @"C:\Users\rfranklin\Documents\ProjectData.txt";
                string[] linesArr = File.ReadAllLines(filePath);
    
                //find matches
                foreach(string s in linesArr)
                {
                    if(s.Contains(citation))
                    {
                        matchedList.Add(s); //matched
                    }
                }
    
                //output
                foreach(string s in matchedList)
                {
                    Console.WriteLine(s); //write to console
                    //or output to wherever you wish, eg.
                    //richTextBox.Text += s + "\n";
                }
            }
        }
    }
    

    请注意,Form1 需要从其他地方调用并接受citation 参数。要独立测试,请将其更改为

        public Form1()
        {
            InitializeComponent();
    
            string citation = "S8729936";
    

    【讨论】:

      【解决方案3】:

      如果 CSV 文件中的行数不是太大(我不知道“太大”是什么),那么您可以利用一些 .NET 结构,例如 Data Binding 和 Linq 来实现这一点。

      对于初学者,我将创建一个实现 INotifyPropertyChanged 的类:

      namespace Citations
      {
          public class Citation : INotifyPropertyChanged
          {
      
              public static Citation ParseLine(string line)
              {
                  Citation cit = new Citation();
      
                  if (string.IsNullOrEmpty(line))
                      throw new ArgumentException("Invalid argument", nameof(line));
      
                  string[] vals = line.Split(',');
      
                  if (vals.Length != 6)
                      throw new ArgumentOutOfRangeException(nameof(line), "Invalid format");
      
                  cit.CitationNumber = vals[0].Trim();
                  cit.PlateNumber = vals[1].Trim();
                  cit.DateCreated = DateTime.Parse(vals[2].Trim());
                  cit.DateExpired = DateTime.Parse(vals[3].Trim());
                  cit.Status = vals[4].Trim();
                  cit.Amount = Decimal.Parse(vals[5].Trim());
      
                  return cit;
      
              }
      
              void RaisePropertyChanged(string prop)
              {
                  if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(prop)); }
              }
              public event PropertyChangedEventHandler PropertyChanged;
      
              string citationNumber;
              public string CitationNumber
              {
                  get
                  {
                      return citationNumber;
                  }
                  set
                  {
                      if (citationNumber != value)
                      {
                          citationNumber = value;
                          RaisePropertyChanged(nameof(CitationNumber));
                      }
                  }
              }
      
              string plateNumber;
              public string PlateNumber
              {
                  get
                  {
                      return plateNumber;
                  }
                  set
                  {
                      if (plateNumber != value)
                      {
                          plateNumber = value;
                          RaisePropertyChanged(nameof(PlateNumber));
                      }
                  }
              }
      
              DateTime dateCreated;
              public DateTime DateCreated
              {
                  get
                  {
                      return dateCreated;
                  }
                  set
                  {
                      if (dateCreated != value)
                      {
                          dateCreated = value;
                          RaisePropertyChanged(nameof(DateCreated));
                      }
                  }
              }
              DateTime dateExpired;
              public DateTime DateExpired
              {
                  get
                  {
                      return dateExpired;
                  }
                  set
                  {
                      if (dateExpired != value)
                      {
                          dateExpired = value;
                          RaisePropertyChanged(nameof(DateExpired));
                      }
                  }
              }
      
              string status;
              public string Status
              {
                  get
                  {
                      return status;
                  }
                  set
                  {
                      if (status != value)
                      {
                          status = value;
                          RaisePropertyChanged(nameof(Status));
                      }
                  }
              }
      
              Decimal amount;
              public Decimal Amount
              {
                  get
                  {
                      return amount;
                  }
                  set
                  {
                      if (amount != value)
                      {
                          amount = value;
                          RaisePropertyChanged(nameof(Amount));
                      }
                  }
              }
      
      
          }
      }
      

      该类负责从 CSV 文件中拆分一行,并将其转换为 Citation 类型的对象,稍后将用于对 Form2 中的文本框进行数据绑定。

      然后在第一个表单中,我会简单地读取文件,并使用一些 Linq 运算符,将文件转换为引文对象字典,字典的键是引文编号:

      private void button1_Click(object sender, EventArgs e)
      {
          string[] allLines = File.ReadAllLines("Citations.csv");
      
          Dictionary<string, Citation> dict = allLines.Select(l => Citation.ParseLine(l)).ToDictionary(c => c.CitationNumber, k => k);
      
          Citation cit = dict["W2041810"];
      
          Form2 frm2 = new Form2();
          frm2.SetCitation(cit);
          frm2.ShowDialog();
      }
      

      在上面的代码中,我们使用ToDictionary Linq 运算符从您的 Citation 对象创建一个字典,Dictionat 键是引文编号。

      在这里,我对其中一个引用进行硬编码以供查找并传递给 Form2,它的 SetCitation 方法如下:

      public void SetCitation(Citation citation)
      {
          this.citationBindingSource.DataSource = citation;
      }
      

      Form2 的代码有点难以显示,因为我使用表单设计器为每个 TextBox 设置数据绑定,如果我想显示,我基本上必须显示整个 Form2.Designer。 .cs 文件。

      相反,我建议指导您完成创建项目数据源的过程,然后从 Visual Studio 的数据源对话框中将文本框拖放到 Form2 上。

      因此,在将 Citation 类添加到您的解决方案后,请确保至少编译一次,以便“添加数据源”向导将该类选为可能的数据源。

      然后,通过转到“查看”>“其他窗口”>“数据源”(假设此处为 Visual Studio 2015)确保显示“数据源”对话框。

      从“数据源”对话框中,单击“添加新数据源”按钮以启动“数据源配置向导”。从可能的数据源列表中,您将选择“对象”:

      然后单击下一步按钮。在下一个向导步骤中,您将选择 Citation 类:

      然后点击完成按钮。

      在“数据源”对话框中,您现在应该有如下内容:

      从此数据源对话框中,您现在可以将各个字段拖放到 Form2 上,这应该会为您提供如下内容:

      您还会注意到,在 Form2 的 Component 托盘中,添加了一个 BindingSource 对象:

      在后台,Visual Studio 将设置所有引文对象属性的数据绑定以显示在相应的文本框中。

      这是一种“粘合剂”,可以使用 Citation 对象调用 Form2.SetCitation(),并将所有字段显示在应有的位置。

      我知道这很难咀嚼,但相信我,一旦你理解了这背后的原理,你就不会想回到你开始实施的那种 spagethi 代码(无意冒犯,我们已经都去过)。

      如果您希望我澄清答案的任何特定部分,请告诉我,我会相应地进行编辑。

      干杯

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-12-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-18
        相关资源
        最近更新 更多