gpt4 book ai didi

c# - 将 dataGridView 列转换为复选框列

转载 作者:太空宇宙 更新时间:2023-11-03 13:41:34 24 4
gpt4 key购买 nike

我正在制作一个程序来检查我在大学里还剩多少门类(class)。我从 csv 加载信息,将其数据放入数据集并使用数据网格显示。

我想要一些列(实验室和理论)有复选框单元格,这样我就可以检查我通过的类(class),然后将它们保存回 csv 以便稍后再次加载它们(当我通过一些东西时:P).但是我在将这些(字符串)列转换为复选框时遇到了问题,因为我在 c# 方面经验不足

这是我的代码:

string delimiter = ";";
string tablename = "paTable";
filename = "aname";
DataSet dataset = new DataSet();
StreamReader sr = new StreamReader(filename);
DataGridViewColumn column = new DataGridViewColumn();
dataset.Tables.Add(tablename);

dataset.Tables[tablename].Columns.Add("A/A");
dataset.Tables[tablename].Columns.Add("Course");
dataset.Tables[tablename].Columns.Add("Semester");
dataset.Tables[tablename].Columns.Add("Theory");
dataset.Tables[tablename].Columns.Add("Lab");
dataset.Tables[tablename].Columns.Add("Passed");

string alldata = sr.ReadLine();
while (sr.Peek() != -1)
{
alldata = sr.ReadLine();
string[] rows;
rows = alldata.Split("\r".ToCharArray());

foreach (string r in rows)
{
string[] items = r.Split(delimiter.ToCharArray());
dataset.Tables[tablename].Rows.Add(items);
}

this.dataGridView1.DataSource = dataset.Tables[0].DefaultView;
}

如有任何帮助,我们将不胜感激!

最佳答案

如果您手动创建列并将其添加到您的 DataGridView,我认为您可以保持 DataSet 加载过程不变。

关闭 AutoGenerateColumns 并手动添加它们:

dataGridView1.AutoGenerateColumns = false;
dataGridView1.Columns.Add(new DataGridViewTextBoxColumn { Name="Course", ... } );
dataGridView1.Columns.Add(new DataGridViewCheckBoxColumn { Name="Passed", ... } );
...

GridView 应该在您将它与 DataView 绑定(bind)后填充,就像您正在做的那样:

dataGridView1.DataSource = dataset.Tables[0].DefaultView;

编辑

因为它依赖于强类型和适当的绑定(bind),一个更好的选择可能是创建一个类来表示 CSV 记录(假设类型)。如果此类实现了 INotifyPropertyChanged 接口(interface),则可以在 DataGridView 中编辑这些值,并以最小的努力反射(reflect)在该类中。

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 然后可以绑定(bind)到 CsvDataSource 实例的 Rows 属性,因此表单的代码可以如下所示:

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 block 中。

这是一个快速总结的实现,确实需要一些额外的工作才能完全发挥作用,但它提供了一个想法,并且开箱即用。

这样,“定义列”部分在 CsvDataRow 类中完全得到处理,该类为每条记录提供强类型。没有 DataSet,没有 DataColumn,也没有 DataGridViewColumn。只有数据和一些数据绑定(bind)。

关于c# - 将 dataGridView 列转换为复选框列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16796933/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com