C# 如何将多个CSV文件中的数据读取到折线图中

C# 如何将多个CSV文件中的数据读取到折线图中,c#,winforms,csv,C#,Winforms,Csv,目前,我的代码可以使用OpenFileDialog和MultiSelect=True选择多个csv文件。但我的图表似乎只从一个csv文件中获取数据,而不是从其他csv文件中获取数据 我的所有csv文件只有2列(X轴和Y轴): 我需要能够从多个csv文件中获取数据,并生成具有多行的图形(例如,3个csv文件=图形中显示的3行) 如果有人能在这方面帮助我,我真的很感激 谢谢。当您使用Multiselect时,您必须循环浏览用户选择的所有文件,而不是使用OpenFile()方法,因为它只适用于一个文件

目前,我的代码可以使用
OpenFileDialog
MultiSelect=True
选择多个csv文件。但我的图表似乎只从一个csv文件中获取数据,而不是从其他csv文件中获取数据

我的所有csv文件只有2列(X轴和Y轴):

我需要能够从多个csv文件中获取数据,并生成具有多行的图形(例如,3个csv文件=图形中显示的3行)

如果有人能在这方面帮助我,我真的很感激


谢谢。

当您使用
Multiselect
时,您必须循环浏览用户选择的所有文件,而不是使用
OpenFile()
方法,因为它只适用于一个文件

if (ff.ShowDialog() == DialogResult.OK)
{
    //if ((myStream = ff.OpenFile()) != null)
    foreach (String file in ff.FileNames)
    {
        myStream = File.OpenRead(file);
        // ...
    }
}

编辑:关于需要修改的代码的其他部分:

您必须将
rrList
用作
List
,而不仅仅是一个rr

GraphDemo.cs

    Read rr;
    List<Read> rrList = new List<Read>(); // *** new

    void openToolStripMenuItem_Click(object sender, EventArgs e)
    {
        Stream myStream = null;
        OpenFileDialog ff = new OpenFileDialog();

        ff.InitialDirectory = "C:\\";
        ff.Filter = "csv files (*.csv)|*.csv|All files (*.*)|*.*";
        ff.Multiselect = true;
        ff.FilterIndex = 1;
        ff.RestoreDirectory = true;

        if (ff.ShowDialog() == DialogResult.OK)
        {
            try
            {
                rrList.Clear(); //***
                foreach (String file in ff.FileNames) //if ((myStream = ff.OpenFile()) != null)
                {
                    using (myStream = File.OpenRead(file))
                    {
                        rr = new Read(myStream);
                        rr.fileName = Path.GetFileName(file);  // !!! new
                        string[] header = rr.get_Header();
                        List<string> lX = new List<string>();
                        List<string> lY = new List<string>();
                        for (int i = 0; i < header.Length; i++)
                        {
                            lX.Add(header[i]); lY.Add(header[i]);
                        }
                        //Populate the ComboBoxes
                        xBox.DataSource = lX;
                        yBox.DataSource = lY;
                        // Close the stream
                        myStream.Close();
                    }
                    rrList.Add(rr); //***
                }
            }
            catch (Exception err)
            {
                //Inform the user if we can't read the file
                MessageBox.Show(err.Message);
            }
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {

        Plot p = new Plot(rrList, xBox, yBox, chart); //*** use rrList instead of rr

    }
class Plot
{
    public Plot(List<Read> rrList, ComboBox xBox, ComboBox yBox, Chart chart) //***
    {
        int indX = xBox.SelectedIndex;
        int indY = yBox.SelectedIndex;

        chart.Series.Clear(); //ensure that the chart is empty
        chart.Legends.Clear();
        Legend myLegend = chart.Legends.Add("myLegend"); // !!! new
        myLegend.Title = "myTitle"; // !!! new

        int i = 0; //series index
        foreach (Read rr in rrList)
        {
            float[,] data = rr.get_Data();
            int nLines = rr.get_nLines();
            int nColumns = rr.get_nColumns();
            string[] header = rr.get_Header();

            chart.Series.Add("Series" + i);
            chart.Series[i].ChartType = SeriesChartType.Line;

            chart.Series[i].LegendText = rr.fileName; // !!! new

            chart.ChartAreas[0].AxisX.LabelStyle.Format = "{F2}";
            chart.ChartAreas[0].AxisX.Title = header[indX];
            chart.ChartAreas[0].AxisY.Title = header[indY];

            for (int j = 0; j < nLines; j++)
            {
                chart.Series[i].Points.AddXY(data[j, indX], data[j, indY]);
            }

            i++; //series index
        }
    }
}

注意:您的代码方法不太好,例如,Plot应该是its类中的一个void方法,而不是构造函数,因为每次您想要绘制一个不需要的新Plot时,都必须重新创建Plot的一个新实例。还有很多其他的提示。。。但是它是有效的

你可能应该通过阅读来增加别人帮助你的几率。就目前而言,我认为没有人会通读你所有的代码。谢谢你的回答。我可以知道我是否需要更改Plot.cs或Read.cs中的任何内容吗?我已尝试添加您的代码,但它在图形中仅显示一行,即使我选择了2个csv文件。是的,您必须更新代码的其他部分。看我的编辑是的,现在可以了!非常感谢。另一个简短的问题是,如何根据输入文件名在两侧添加图例?对“Chart1.Legends.Add”有一些问题。已接受。我无法根据打开的文件显示图例。例如,打开了1.csv和2.csv,但图例没有相应显示。您必须将文件名作为新属性保留在Read类中,并在打印期间使用它。我将发布对code
chart.Series[i].LegendText=rr.fileName的更新
class Plot
{
    public Plot(List<Read> rrList, ComboBox xBox, ComboBox yBox, Chart chart) //***
    {
        int indX = xBox.SelectedIndex;
        int indY = yBox.SelectedIndex;

        chart.Series.Clear(); //ensure that the chart is empty
        chart.Legends.Clear();
        Legend myLegend = chart.Legends.Add("myLegend"); // !!! new
        myLegend.Title = "myTitle"; // !!! new

        int i = 0; //series index
        foreach (Read rr in rrList)
        {
            float[,] data = rr.get_Data();
            int nLines = rr.get_nLines();
            int nColumns = rr.get_nColumns();
            string[] header = rr.get_Header();

            chart.Series.Add("Series" + i);
            chart.Series[i].ChartType = SeriesChartType.Line;

            chart.Series[i].LegendText = rr.fileName; // !!! new

            chart.ChartAreas[0].AxisX.LabelStyle.Format = "{F2}";
            chart.ChartAreas[0].AxisX.Title = header[indX];
            chart.ChartAreas[0].AxisY.Title = header[indY];

            for (int j = 0; j < nLines; j++)
            {
                chart.Series[i].Points.AddXY(data[j, indX], data[j, indY]);
            }

            i++; //series index
        }
    }
}
public string fileName { get; set; } // !!! new