#c_sharp #winforms #datagridview
Создаю другой DataGridView, скопировал массив строк из одного, хочу добавить в другой. Ошибка, надо чтобы столбцы совпадали. Через цикл скопировал название и тип столбцов. Ошибка, такой столбец уже есть (тут уже возникло недоумение). Что только не перепробовал. И в DataView пытался превращать и в DataTable. В общем. Есть одна таблица, заполняемая так: counterpartyListGV.ReadOnly = false; MDM_DBDataSetTableAdapters.PERSONTableAdapter Ptb = new MDM_DBDataSetTableAdapters.PERSONTableAdapter(); Ptb.Fill(mainForm.MDM_DS.PERSON); var checkBoxColumn = new DataGridViewCheckBoxColumn(); checkBoxColumn.HeaderText = ""; checkBoxColumn.Name = "CheckBoxColumn"; checkBoxColumn.ReadOnly = false; checkBoxColumn.FalseValue = false; checkBoxColumn.TrueValue = true; counterpartyListGV.Columns.Add(checkBoxColumn); for (int i = 1; i < counterpartyListGV.Columns.Count; i++) counterpartyListGV.Columns[i].ReadOnly = true; counterpartyListGV.DataSource = mainForm.MDM_DS.PERSON.DefaultView; Нужно скопировать те строки, которые отмечены галочкой в первом (дополнительном) столбце. upd.: Сейчас вот тоже пытаюсь вставить построчно те строки, что отмечины галкой в первом столбце. DataGridView mergeRows = new DataGridView(); for (int i = 0; i < counterpartyListGV.Rows.Count; i++) if (((DataGridViewCheckBoxCell)counterpartyListGV.Rows[i].Cells[0]).Value != null && (bool)((DataGridViewCheckBoxCell)counterpartyListGV.Rows[i].Cells[0]).Value) { mergeRows.Rows.Add(counterpartyListGV.Rows[i].Cells); } Но так не работает (мол, нет столбцов в новом DataGridView). Пытаюсь добавить столбцы: DataGridViewColumn[] a = new DataGridViewColumn[counterpartyListGV.Columns.Count]; counterpartyListGV.Columns.CopyTo(a, 0); mergeRows.Columns.AddRange(a); Говорит, что "Указанный столбец уже принадлежит к элементу управления DataGridView". Уфф.
Ответы
Ответ 1
Одно из основополагающих правил современной разработки - данные должны быть отделены от представления. У вас данные хранятся в DataTable - вот с ним и нужно работать. А DataGridView - это представление - не трогаем его, просто используем привязку данных. Я набросал полностью рабочий пример. Данные заносятся в DataTable в коде, а не из БД. using System; using System.Data; using System.Drawing; using System.Windows.Forms; namespace WindowsFormsApp1 { public partial class Form1 : Form { DataGridView dataGridView1; DataGridView dataGridView2; DataTable dataTable; public Form1() { //InitializeComponent(); Size = new Size(400, 400); dataGridView1 = new DataGridView { Parent = this, Dock = DockStyle.Top }; dataGridView2 = new DataGridView { Parent = this, Dock = DockStyle.Bottom }; // Здесь ваш код чтения данных из БД dataTable = new DataTable(); dataTable.Columns.Add("Id", typeof(int)); dataTable.Columns.Add("Name", typeof(string)); dataTable.Rows.Add(1, "Bob"); dataTable.Rows.Add(2, "Alice"); // Добавляем колонку в источник данных dataTable.Columns.Add("Check", typeof(bool)); // Делаем привязку данных dataGridView1.DataSource = dataTable; new Button { Parent = this, Top = dataGridView1.Bottom + 10, Text = "Copy" } .Click += ButtonCopy_Click; } private void ButtonCopy_Click(object sender, EventArgs e) { // Создаём вью var dv = new DataView(dataTable); // Фильтруем данные во вью dv.RowFilter = "Check = true"; // Делаем привязку данных dataGridView2.DataSource = dv; // Скрываем колонку, если не нужна dataGridView2.Columns["Check"].Visible = false; } } } Обратите внимание, все манипуляции осуществляются непосредственно с источником данных - DataTable. Мы практически не касаемся DataGridView.Ответ 2
Я решал подобную проблему следующим образом: for (int i = 0; i < dataGrid.Rows.Count; i++) { DataGridViewRow row = new DataGridViewRow(); row = (DataGridViewRow)dataGrid.Rows[i].Clone(); int intColIndex = 0; foreach (DataGridViewCell cell in dataGrid.Rows[i].Cells) { row.Cells[intColIndex].Value = cell.Value; intColIndex++; } DateTime end_date = Convert.ToDateTime(dataGrid.Rows[i].Cells[5].Value); int diff = (end_date - today).Days; if (diff > 20 || Convert.ToInt32(dataGrid.Rows[i].Cells[6].Value) != 0) { continue; } DeadLinesDataGridView.Rows.Add(row); } Мне надо было скопировать в DeadLinesDataGridView все записи, у которых до завершения осталось < 20 дней. Я копировал строку методом DataGridViewRow.Clone(), потом переносил все данные по ячейкам из одной строки в другую и вставлял в нужную таблицу.Ответ 3
Не дождался ответа, пока так сделал (вроде работает) не знаю, как насчет оптимальности. DataGridView mergeRows = new DataGridView(); foreach (DataGridViewColumn Col in counterpartyListGV.Columns) mergeRows.Columns.Add((DataGridViewColumn)Col.Clone()); for (int i = 0; i < counterpartyListGV.Rows.Count; i++) if (((DataGridViewCheckBoxCell)counterpartyListGV.Rows[i].Cells[0]).Value != null && (bool)((DataGridViewCheckBoxCell)counterpartyListGV.Rows[i].Cells[0]).Value) { DataGridViewRow row = (DataGridViewRow)(counterpartyListGV.Rows[i]).Clone(); for (int j = 0; j < counterpartyListGV.Rows[i].Cells.Count; j++) row.Cells[j].Value = counterpartyListGV.Rows[i].Cells[j].Value; mergeRows.Rows.Add(row); }Ответ 4
Привет вот я так сделал namespace DataGrid { public partial class Form1 : Form { Listhumans = new List (); DataTable Table = new DataTable(); public Form1() { InitializeComponent(); humans = new List () { new Human(){ Name = "John", Age = 12}, new Human(){ Name = "Alexis", Age = 13}, new Human(){ Name = "Alura", Age = 21}, new Human(){ Name = "Grey", Age = 7}, new Human(){ Name = "Mike", Age = 12}, new Human(){ Name = "Philip", Age = 12} }; View.DataSource = humans; } private void button1_Click(object sender, EventArgs e) { Table.AsDataView(); if(Table.Columns.Count == 0) { Table.Columns.Add("Имя", Type.GetType("System.String")); Table.Columns.Add("Возраст", Type.GetType("System.String")); } for (int i = 0; i < View.SelectedRows.Count; i++) { var values = new List
Комментариев нет:
Отправить комментарий