Страницы

Поиск по вопросам

суббота, 14 декабря 2019 г.

Как скопировать строки из DataGridView?

#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 { List humans = 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(); for (int j = 0; j < View.SelectedRows[i].Cells.Count; j++) { values.Add(View.SelectedRows[i].Cells[j].Value); } Table.Rows.Add(values.ToArray()); } dataGridView1.DataSource = Table; } } class Human { public string Name { get; set; } public int Age { get; set; } } }

Комментариев нет:

Отправить комментарий