windows - C # udfyld DataGridView ved retur fra anden klasse

Indlæg af Hanne Mølgaard Plasc

Problem



Hej Jeg har et program til at analysere en CSV og udfylde den i en DataGridView.


Når jeg gør det sådan, virker det godt:


        openFileDialog1.Filter = "CSV Files(*.csv)|*.csv";
        openFileDialog1.FilterIndex = 1;
        openFileDialog1.RestoreDirectory = true;

        if (openFileDialog1.ShowDialog() == DialogResult.OK)
        {
            txtCsvSource.Text = openFileDialog1.FileName;
            Encoding iso = Encoding.GetEncoding("ISO-8859-1");
            using (CachedCsvReader csv = new CachedCsvReader(new StreamReader(txtCsvSource.Text, iso), true))
            {
               csv.MissingFieldAction = MissingFieldAction.ReplaceByEmpty;
               dataGridView1.DataSource = csv;
            }
        }


Men når jeg gør det sådan:


        openFileDialog1.Filter = "CSV Files(*.csv)|*.csv";
        openFileDialog1.FilterIndex = 1;
        openFileDialog1.RestoreDirectory = true;

        if (openFileDialog1.ShowDialog() == DialogResult.OK)
        {
            txtCsvSource.Text = openFileDialog1.FileName;
            dataGridView1.DataSource = QrFunctions.parsecsv(txtCsvSource.Text);
            dataGridView1.Update();
        }


med QrFunctions.parsecsv er som:


public CachedCsvReader parsecsv(string csvpath)
    {
        Encoding iso = Encoding.GetEncoding("ISO-8859-1");
        using (CachedCsvReader csv = new CachedCsvReader(new StreamReader(csvpath, iso), true))
        {
            csv.MissingFieldAction = MissingFieldAction.ReplaceByEmpty;
            return csv;
        }
    }


DataGridView er tom ... hvorfor? Jeg har simpelthen ingen anelse :-( Jeg ville bare bruge denne funktion til at analysere i en anden klasse, så jeg lavede klassen QrFunctions.

Bedste reference


Prøv dette.


public CachedCsvReader parsecsv(string csvpath)
    {   
        Encoding iso = Encoding.GetEncoding("ISO-8859-1");
        CachedCsvReader csv = new CachedCsvReader(new StreamReader(csvpath, iso), true)
        {
            csv.MissingFieldAction = MissingFieldAction.ReplaceByEmpty;
            return csv;
        }
    }


Husk at bortskaffe objektet selv, da jeg har fjernet brugsanvisningen eller implementer det IDisposable mønster [15]


Takket være @MartiniMoe for konstruktive kommentarer.

Andre referencer 1


Alykhalids svar var næsten korrekt, medmindre det ser ud til, at Dispose metoden i CachedCsvReader kalder DisposeStreamReader.


Alt en brug erklæring er, er syntaktisk sukker for følgende kode:


try
{
    var yourObject = new SomeIDisposable();
    // Some code using yourObject
}
finally
{
    yourObject.Dispose();
}


Så brugeren omkring CachedCsvReader ringer til Dispose () -metoden til læseren, som jeg gætter på, ser noget ud:


void Dispose()
{
    streamReader.Dispose();
}


Så snart du er uden for den anvendte blok, er bortskaffelse blevet kaldt på StreamReader og selv når du kopierer din csv-læserreference til et objekt uden for brugen, er din strøm selv lukket, så din DataGridView modtager ingen data.


Som du har fundet, kan dette løses ved at fjerne den anvendte sætning, men det har den ulempe, at du nu ikke lukker din strøm, hvilket kan have nogle uønskede effekter.


For at følge sikreste praksis skal du enten:



  • Gør QrFunctions implementere IDisposable, så du kan bruge en brugserklæring (som virkelig sætter dig tilbage, hvor du startede)

  • Ring .Dispose () på den CachedCsvReader, du vender tilbage.

  • Sæt brugsfortegnelsen tilbage i din hjælperfunktion, men læs strømmen indenfor brugen - forhåbentlig kan CSV-læseren blive tvunget til at læse med det samme og returnere en slags liste over csv-rækker. Så vender du bare tilbage til listen i stedet for CSV-læseren. Din kode vil se lidt ud:


    public List<CSVRows> parsecsv(string csvpath)
    {
        Encoding iso = Encoding.GetEncoding("ISO-8859-1");                       
        using (CachedCsvReader csv = new CachedCsvReader(new StreamReader(csvpath, iso), true))                       
        {                       
            csv.MissingFieldAction = MissingFieldAction.ReplaceByEmpty;                       
            // I have no idea what this method is but if it exists it could be called ToList or Read    
            return csv.ToList<CSVRows>();                       
        } 
    }