列を手動で作成して に追加した場合、ロードプロセスをそのままDataGridView
維持できると思います。DataSet
それらをオフAutoGenerateColumns
にして手動で追加します。
dataGridView1.AutoGenerateColumns = false;
dataGridView1.Columns.Add(new DataGridViewTextBoxColumn { Name="Course", ... } );
dataGridView1.Columns.Add(new DataGridViewCheckBoxColumn { Name="Passed", ... } );
...
DataView
あなたがやっているのと同じようにバインドした後、グリッドビューにデータが入力されるはずです:
dataGridView1.DataSource = dataset.Tables[0].DefaultView;
編集
強力な型と適切なバインディングに依存しているため、CSV レコードを表すクラスを作成することをお勧めします (型が想定されます)。このクラスがインターフェースを実装する場合、最小限の労力でINotifyPropertyChanged
値を編集してクラスに反映させることができます。DataGridView
public class CsvDataRow : INotifyPropertyChanged
{
private bool _aa;
private string _course;
private int _semester;
private double _theory;
private double _lab;
private bool _passed;
public bool AA { get { return _aa; } set { if (value == _aa) return; _aa = value; NotifyPropertyChanged("AA"); } }
public string Course { get { return _course; } set { if (value == _course) return; _course = value; NotifyPropertyChanged("Course"); } }
public int Semester { get { return _semester; } set { if (value == _semester) return; _semester = value; NotifyPropertyChanged("Semester"); } }
public double Theory { get { return _theory; } set { if (value == _theory) return; _theory = value; NotifyPropertyChanged("Theory"); } }
public double Lab { get { return _lab; } set { if (value == _lab) return; _lab = value; NotifyPropertyChanged("Lab"); } }
public bool Passed { get { return _passed; } set { if (value == _passed) return; _passed = value; NotifyPropertyChanged("Passed"); } }
char _delimiter;
// static factory method creates object from CSV row
public static CsvDataRow Create(string row, char delimiter)
{
return new CsvDataRow(row, delimiter);
}
// private constructor initializes property values
private CsvDataRow(string row, char delimiter)
{
_delimiter = delimiter;
var values = row.Split(_delimiter);
AA = (values[0].ToString().Equals("1"));
Course = Convert.ToString(values[1]);
Semester = Convert.ToInt32(values[2]);
Theory = Convert.ToDouble(values[3]);
Lab = Convert.ToDouble(values[4]);
Passed = (values[5].ToString().Equals("1"));
}
// a method to convert back into a CSV row
public string ToCsvString()
{
var values = new string[] { (AA ? 1 : 0).ToString(), Course, Semester.ToString(), Theory.ToString(), Lab.ToString(), (Passed ? 1: 0).ToString() };
return string.Join(_delimiter.ToString(), values);
}
// INotifyPropertyChanged interface requires this event
public event PropertyChangedEventHandler PropertyChanged;
// helper method to raise PropertyChanged event
private void NotifyPropertyChanged(string name)
{
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
CSV ファイル自体は、次のクラスで表すことができます。
public class CsvDataSource
{
public char Delimiter { get; private set; }
public CsvDataSource()
: this(',')
{ }
public string[] Columns { get; private set; }
public ObservableCollection<CsvDataRow> Rows { get; private set; }
public CsvDataSource(char delimiter)
{
Delimiter = delimiter;
}
public void LoadCsv(string csvFileName)
{
string header;
string data;
using (var reader = new StreamReader(csvFileName))
{
header = reader.ReadLine(); // assumes 1st row is column headers
data = reader.ReadToEnd();
}
Columns = header.Split(Delimiter);
var rows = Regex.Split(data, Environment.NewLine);
if (!rows.Select(row => row.Split(Delimiter)).All(row => row.Length == Columns.Length)) throw new FormatException("Inconsistent data format.");
Rows = new ObservableCollection<CsvDataRow>(rows.Select(row => CsvDataRow.Create(row, Delimiter)));
}
}
その後、DataGridView をインスタンスのRows
プロパティにバインドできるCsvDataSource
ため、フォームのコードは次のようになります。
public partial class Form1 : Form
{
private CsvDataSource _data;
private ObservableCollection<CsvDataRow> _rows;
public Form1()
{
InitializeComponent();
}
public void LoadCsv(CsvDataSource data)
{
_data = data;
_rows = _data.Rows;
dataGridView1.DataSource = _rows;
}
public void SaveCsv(string path)
{
using (var writer = new StreamWriter(path))
{
writer.WriteLine(string.Join(_data.Delimiter.ToString(), _data.Columns));
foreach (var row in _rows)
{
writer.WriteLine(row.ToCsvString());
}
}
}
}
もちろん、SaveCsv
メソッドを呼び出すボタンがあり、別のボタンで DataGridView との間で行を追加/削除する必要があります。また、ファイル I/O 操作を try/cath ブロックでラップすることもできます。
これは簡単にまとめた実装であり、完全に機能させるには少し追加作業が必要ですが、アイデアが得られ、すぐに使用できます。
このように、「列の定義」部分はCsvDataRow
、各レコードに強い型を提供するクラスで完全に処理されます。いいえDataSet
、いいえDataColumn
、いいえDataGridViewColumn
。データのみ、およびいくつかのデータ バインディング。