В форме Windows у меня есть два несвязанных столбца представления сетки данных, каждый со своим заголовком, и я пытаюсь прочитать файл csv в таблице данных и привязать его к сетке.
Только я не знаю логики. Я не знаю, как связать данные с двумя столбцами представления сетки данных. Существует множество примеров того, как связать данные csv с представлением сетки, но они имеют дело с заголовками, которые считываются из файла, а не с несвязанными, за исключением этого, но это с asp. Программно отображать данные в столбце представления сетки
Вот данные из файла csv.
Address,76 Douglas St Wakecorn
Property name,Wakecorn University
Building,C Block
Room,C2.18
Вот код класса, который его читает.
public class Setting
{
private DataTable _dt { get; set; }
public DataTable ProcessSettingFileCMD(string filePath)
{
if (_dt == null)
{
populateControlWithCSVData(filePath);
}
}
private void populateControlWithCSVData(string filePath)
{
_dt = new DataTable();
string[] lines = File.ReadAllLines(filePath);
if (lines.Length > 0)
{
for(int row = 1; row < lines.Length; row++)
{
string[] dataWords = lines[row].Split(',');
DataRow dr = _dt.NewRow();
foreach (string word in lines)
{
dr[word] = dataWords[row++];
}
_dt.Rows.Add(dr);
}
}
}
}
Вот форма
private void mnuOpen_Click(object sender, EventArgs e)
{
openFD.InitialDirectory = "C:\\";
openFD.ShowDialog();
_dt = _objSetting.ProcessSettingFileCMD(openFD.FileName);
if (_dt.Rows.Count > 0)
{
gvSettings.DataSource = _dt;
}
}
Возвращаемая ошибка находится здесь dr[word] = dataWords[row++];
System.ArgumentException: 'Column 'Address,76 Douglas St Wakecorn' does not belong to table .
Первая строка CSV обычно содержит заголовок столбца (имена столбцов). Используйте этот заголовок для создания столбцов вашей таблицы данных. Тогда это не способ добавить строку: dr[word] = dataWords[row++]; => dr[word]
указывает либо имя столбца, либо индекс столбца. Не текущее содержимое поля. Наконец, для столбцов DataGridView уже должно быть установлено свойство DataPropertyName
, равное соответствующему имени столбца DataTable. В этом случае вы также можете автоматически генерировать столбцы DGV. Или добавьте их в код, указав DataType, если это необходимо.
DataRow имеет упрощенный конструктор, который использует object[]
в качестве источника. Это будет массив строк: он у вас уже есть из Split()
.
@haldo CSV повторяется. Таким образом, он отображает все данные в виде сетки. Первоначально у него был цикл, который печатал первую строку в CSV в качестве заголовков, которые я вынул, потому что у меня уже были несвязанные столбцы. Один несвязанный столбец предназначался для описания, а другой — для данных. Оба несвязанных столбца имеют собственные заголовки. Таким образом, описание может содержать «Адрес», а данные могут содержать «76 Douglas St Wakecorn». Тем не менее, вы говорите, что проще иметь Address, Property name, Building, Room
в качестве заголовков? Я надеялся, что все это будет в виде значений csv в одном столбце для описания.
@Jimi Но я хочу использовать несвязанные столбцы, которые я сделал в дизайнере, в качестве заголовков. Как я могу это сделать? Итак, я хочу привязать Address, PropertyName, Building, Room
как значения к первому столбцу и Douglas St Wakecorn, Wakecorn University, C Block, C2.18
как значения ко второму столбцу.
Это не файл CSV. Это пользовательский формат, который вы (или кто-то другой) придумали. В любом случае, не проблема, если файл содержит только один блок информации. Или, если он содержит больше блоков информации, все (всегда) занимающие 4 строки. Вы можете читать 4 строки одновременно, Split(
,)
каждую строку, добавляя содержимое dataWords[0]
к строке (строка1) и содержимое dataWords[1]
к другой (строка2). Затем создайте DataRow, используя (string1) в качестве значения первого столбца и (string2) для второго столбца.
Обратите внимание, что вы должны добавить два столбца в DataTable, используя те же имена, которые вы установили в конструкторе DGV в качестве свойства DataPropertyName
. В противном случае вы получите 4 столбца вместо 2. Если вы этого не сделаете, те, которые вы установили в дизайнере, будут пустыми.
Кстати, почему бы вам не использовать стандартный формат CSV (с именами полей в первой строке файла)? Это решило бы большинство ваших текущих и, возможно, будущих проблем.
@Jimi Я закопал чей-то обычный формат, а затем попытался его настроить. Причина в том, что я хочу сопоставить все значения в столбце «Данные», чтобы переименовать группу имен файлов в поле перетаскивания. Значения будут записаны во все файлы. Я хотел, чтобы пользователь одним нажатием кнопки создавал CSV-файлы, читал их содержимое в представлении сетки и печатал его в имени файла. Заголовок Description — это просто столбец метаданных, если они создают несколько файлов и забывают, для чего нужны все данные.
В соответствии с предоставленными инструкциями и параметрами я удалил столбцы, созданные в дизайнере, и вместо этого создал их экземпляры при чтении файла CSV.
Также я использовал дочерний класс CsvFileReader, чтобы привязать его к списку строк, а затем к таблице данных. Очень полезно! http://www.blackbeltcoder.com/Articles/files/reading-and-writing-csv-files-in-c
Вот переписанный код.
Форма настроек.
public partial class frmSettings : Form
{
protected string FileName;
protected bool Modified;
Setting _objSetting = new Setting();
OpenFileDialog openFD = new OpenFileDialog();
DataTable _dt = new DataTable();
public frmSettings()
{
InitializeComponent();
}
private void mnuOpen_Click(object sender, EventArgs e)
{
Cursor = Cursors.WaitCursor;
try
{
openFD.Title = "Open a CSV File";
if (SaveIfModified())
{
if (openFD.ShowDialog(this) == DialogResult.OK)
{
_dt = _objSetting.ProcessSettingFileCMD(openFD.FileName);
if (_dt.Rows.Count > 0)
{
gvSettings.DataSource = _dt;
}
}
}
FileName = openFD.FileName;
Modified = false;
}
catch (Exception ex)
{
Debug.WriteLine(String.Format("Error reading from {0}.\r\n\r\n{1}", FileName, ex.Message));
}
finally
{
Cursor = Cursors.Default;
}
}
}
Вот снова класс настроек.
public class Setting
{
private DataTable _dt;
DataColumn _dclColumnDescription = new DataColumn("Description", typeof(string));
DataColumn _dclColumnData = new DataColumn("Data", typeof(string));
public DataTable ProcessSettingFileCMD(string filePath)
{
if (_dt == null)
{
populateControlWithCSVData(filePath);
}
}
private void populateControlWithCSVData(string filePath)
{
_dt = new DataTable();
List<string> columns = new List<string>();
using (var reader = new CsvFileReader(filePath))
{
_dt.Columns.Add(_dclColumnDescription);
_dt.Columns.Add(_dclColumnData);
while (reader.ReadRow(columns))
{
_dt.Rows.Add(columns.ToArray());
}
}
}
}
Повторяются ли данные в CSV или это только одна запись в файле? Кроме того, формат вашего CSV не является стандартным, поскольку каждая запись состоит из нескольких строк и начинается с заголовка/имени. Было бы проще получить доступ к данным, если бы они были в формате
Address, PropertyName, Building, Room
с каждой записью в отдельной строке.