HeyCHのブログ

慢性疲労のへいちゃんです

【C#】CSVを読み込んでDataGridに表示してみよう

今回は、CSVを読み込んでWPFのDataGridに表示する方法を書いていきたいと思います。

TextFieldParserを使用する

f:id:HeyCH:20200605235507p:plain
f:id:HeyCH:20200605235540p:plain

  • コード
<Window x:Class="CsvReader.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:CsvReader"
        mc:Ignorable="d"
        Title="MainWindow" Height="300" Width="400">
    <Grid>
        <DataGrid ItemsSource="{Binding Records}" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding Title}" Header="タイトル"/>
                <DataGridTextColumn Binding="{Binding Price}" Header="価格"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.VisualBasic.FileIO;//TextFieldParserに必要

namespace CsvReader {
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window {
        ViewModel vm = new ViewModel();
        public MainWindow() {
            InitializeComponent();
            vm.Records = new ObservableCollection<Fruit>();
            this.DataContext = vm;

            using (var tfp = new TextFieldParser("test.csv", Encoding.GetEncoding("shift-jis"))) {
                tfp.Delimiters = new[] { "," };
                var headers = tfp.ReadFields();
                while (!tfp.EndOfData) {
                    var data = tfp.ReadFields();
                    if (data.Length >= 2) {
                        vm.Records.Add(new Fruit { Title = data[0], Price = int.Parse(data[1]) });
                    }
                }
            }
        }
    }
    public class ViewModel{
        public ObservableCollection<Fruit> Records { get; set; }
    }
    public class Fruit {
        public string Title { get; set; }
        public int Price { get; set; }
    }
}

CsvHelperを使用する

  • NuGetでCsvHelperをインストールする

f:id:HeyCH:20200606002840p:plain
f:id:HeyCH:20200606002948p:plain

  • コード

XAMLはTextFieldParserの時と同じ

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using CsvHelper;
using CsvHelper.Configuration.Attributes;

namespace CsvReader {
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window {
        ViewModel vm = new ViewModel();
        public MainWindow() {
            InitializeComponent();
            vm.Records = new ObservableCollection<Fruit>();
            this.DataContext = vm;

            using (var reader = new StreamReader("test.csv", Encoding.GetEncoding("shift-jis")))
            using (var csv = new CsvHelper.CsvReader(reader, CultureInfo.InvariantCulture)) {
                var records = csv.GetRecords<Fruit>();
                foreach (var r in records)
                    vm.Records.Add(r);
            }
        }
    }
    public class ViewModel{
        public ObservableCollection<Fruit> Records { get; set; }
    }
    public class Fruit {
        [Index(0)]
        public string Title { get; set; }
        [Index(2)]
        public int Price { get; set; }//2行目にDateを追加してPriceが3行目に来るようにしたCSVを使用
    }
}

f:id:HeyCH:20200606014643p:plain