C # заполните DataGridView при возврате из другого класса - PullRequest
0 голосов
/ 07 марта 2012

Привет, у меня есть программа для анализа CSV и заполнения его в DataGridView.

Когда я так делаю, это прекрасно работает:

        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;
            }
        }

Но когда я делаю это так:

        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();
        }

с QrFunctions.parsecsv, похожим на:

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 пуст ... почему? Я просто понятия не имею :-( Я просто хотел использовать эту функцию для анализа в другом классе, поэтому я создал класс QrFunctions.

Ответы [ 2 ]

1 голос
/ 07 марта 2012

Попробуйте это.

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;
        }
    }

Пожалуйста, не забудьте утилизировать объект самостоятельно, так как я удалил оператор using или реализовал шаблон IDisposable

Благодаря@MartiniMoe за конструктивные комментарии.

0 голосов
/ 07 марта 2012

Ответ Алихалида был почти верным, за исключением того, что похоже на Dispose метод CachedCsvReader, вызывающий Dispose на StreamReader.

Все операторы использования являются синтаксическим сахаром для следующего кода:

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

Таким образом, использование около CachedCsvReader вызывает метод Dispose () читателя, который, как я предполагаю, выглядит примерно так:

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

Таким образом, когда вы находитесь за пределами блока использования, утилита dispose вызывается на StreamReader, и даже когда вы копируете ссылку на читатель csv на объект вне использования, сам ваш поток закрывается, поэтому ваш DataGridView не получает никакого данные.

Как вы обнаружили, это можно исправить, удалив оператор using, но у него есть и обратная сторона: вы сейчас не закрываете свой поток, что может иметь нежелательные эффекты.

Чтобы следовать самым безопасным методам, вы должны либо:

  • Заставьте QrFunctions реализовать IDisposable, чтобы вы могли использовать оператор using (который действительно просто возвращает вас к тому, с чего вы начали)
  • Вызовите .Dispose () для возвращаемого CachedCsvReader.
  • Поместите оператор using обратно в вашу вспомогательную функцию, но прочитайте поток внутри использования - надеюсь, читатель CSV может быть вынужден читать сразу и возвращать какой-то список строк csv. Тогда вы просто возвращаете список, а не читатель CSV. Ваш код будет выглядеть примерно так:

    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>();                       
        } 
    }
    
...