c# datagridview перенос значений из одного datagridview в другой datagridview
пытаюсь сделать Шопинг корзину из datagridivew. выделил товары с помощью Checkbox из одного Грида - в другой копировался выделенные значения. значения переносятся, проблема в том, что при обновлении основного грида выделенные значения во втором гриде - корзине пропадает. как сохранить выделенные значения втором гриде ? Дело в том что основной датагрид фильтруется с помощью Combobox . при каждом фильтраций данные в гриде обновляется
private void button3_Click(object sender, EventArgs e)
{
DataTable dt = new DataTable();
dt.Columns.Add("id");
dt.Columns.Add("Name");
dt.Columns.Add("Qty");
dt.Columns.Add("Category");
dt.Columns.Add("Company");
dt.Columns.Add("Date");
foreach (DataGridViewRow row in dataGridView1.Rows)
{
bool isselect = Convert.ToBoolean(row.Cells["Check1"].Value);
if (isselect)
dt.Rows.Add(row.Cells[1].Value, row.Cells[2].Value, row.Cells[3].Value, row.Cells[4].Value, row.Cells[5].Value, row.Cells[6].Value);
dataGridView2.DataSource = dt;
dataGridView2.Columns[0].Width = 45;
dataGridView2.Columns[1].Width = 150;
dataGridView2.Columns[2].Width = 67;
dataGridView2.Columns[3].Width = 90;
dataGridView2.Columns[4].Width = 105;
dataGridView2.Columns[5].Width = 75;
}
}
public void SelectMetod() // показать данные
{
con.Open();
adapter = new MySqlDataAdapter("SELECT sklad.id, sklad.name, sklad.amount, category.name, company.name, sklad.date FROM sklad LEFT JOIN company ON sklad.companyID = company.id LEFT JOIN category ON sklad.categoryID = category.id", con);
DataSet dset = new DataSet();
adapter.Fill(dset);
dataGridView1.DataSource = dset.Tables[0];
con.Close();
}
DataGridViewCheckBoxColumn checkColumn = new DataGridViewCheckBoxColumn();
checkColumn.Name = "Check1";
checkColumn.HeaderText = "Select";
dataGridView1.Columns.Insert(0, checkColumn);
checkColumn.Width = 45;
private void FilterCategory()
{
string sats = comboBoxCategoryName.Text.ToString();
MySqlCommand command = new MySqlCommand("SELECT sklad.id, sklad.name, sklad.amount, category.name, company.name, sklad.date FROM sklad LEFT JOIN company ON sklad.companyID = company.id LEFT JOIN category ON sklad.categoryID = category.id WHERE category.id = '" + sats + "'", con);
MySqlDataAdapter adapter = new MySqlDataAdapter();
DataTable table = new DataTable();
adapter.SelectCommand = command;
table.Clear();
adapter.Fill(table);
dataGridView1.DataSource = table;
DVGStyle();
}
Метод CreateTable
private DataTable table() // VIEW DATAGRIDVIEW
{
using (MySqlConnection connection = ConDatabase.GetDBConnection())
{
MySqlDataAdapter adapter = new MySqlDataAdapter("SELECT sklad.id, sklad.name, sklad.qty, category.name, company.name, sklad.date FROM sklad LEFT JOIN company ON sklad.companyID = company.id LEFT JOIN category ON sklad.categoryID = category.id", connection);
var dt = new DataTable();
dataGridView1.DataSource = dt;
adapter.Fill(dt);
return dt;
}
}
Ответы (1 шт):
Допустим, вы сделали запрос (скопировал из вашего кода выше) "SELECT sklad.id, sklad.name, sklad.amount, category.name, company.name, sklad.date FROM sklad LEFT JOIN company ON sklad.companyID = company.id LEFT JOIN category ON sklad.categoryID = category.id" и в конечном счёте получили DataTable. Для привязки данных необходимо использовать конкретные классы.
Итак, заходим в гугл и ищем какую-нибудь информацию по запросу "c# datatable to list". Первая же ссылка, но в чём проблема? А в том, что этот код подходит для конкретного запроса, для конкретной таблицы, для конкретного класса. Мы ведь кулл-программисты, которым слишком лень писать один и тот же код, поэтому начинаем гуглить про рефлексию, т.к. именно она может нам помочь в данном вопросе.
Спустя какой-то время мы делаем что-то похожее на, например, это, либо берём этот метод и чуть правим под свои нужды.
Итак, теперь мы имеем на руках List (где T - какой-то наш класс (смотреть эту ссылку для понимания). Нам нужно создать BindingList (где Y - новый класс, который нужно отображать. Если T - тот класс, который нужно отображать, то новый не обязательно создавать) и вставить в него наш List. Делаем это просто через цикл foreach.
После этого нам необходимо привязать наш BindingList к DGV (информация об этом по ссылке выше).
Теперь у нас всё готово для перемещения. Что такое "перемещение выделенной строки из одной таблицы в другую"? Это получения индекса выделенной строки, удаление из одной (в нашем случае, удаление из BindingList) и добавление в другую (другой BindingList). А так как BindingList наследуется от IBindingList, который наследуется от IList, можно сделать вывод, что методы взаимодействия с List здесь точно такие же.
Получить значение - IndexOf() (Подробнее). Далее, удаляем - RemoveItem() (Подробнее). Далее, добавляем - для этого можем использовать Add() (Подробнее) или AddNew() (Подробнее). Скорее всего, вам пригодится простой Add(). Информация про разницу между этими методами
Таким образом, нам осталось лишь получить индекс выделенной строки, по которой мы будем выполнять методы, описанные выше. Гуглим "c# datagridview get selected row index" и получаем в первой же ссылке ответ - datagridview.CurrentCell.RowIndex (Источник)
UPD:
Создаётся впечатление, что вы огромный болт забили на ссылки, которые я кидал вам и пытаетесь скинуть всю свою работу на меня, хотя по факту, делать там почти ничего не нужно. Тем не менее, вот создание привязок:
Создаём Product (Model):
internal class Product : ObservableObject
{
private int _id;
private string _name;
private int _qry;
private string _category;
private DateTime _date;
[DisplayName("Номер услуги")]
public int Id
{
get => _id;
private set
{
_id = value;
OnPropertyChanged(nameof(Id));
}
}
[DisplayName("Название")]
public string Name
{
get => _name;
private set
{
_name = value;
OnPropertyChanged(nameof(Name));
}
}
[DisplayName("Qry")]
public int Qry
{
get => _qry;
private set
{
_qry = value;
OnPropertyChanged(nameof(Qry));
}
}
[DisplayName("Категория")]
public string Category
{
get => _category;
private set
{
_category = value;
OnPropertyChanged(nameof(Category));
}
}
[DisplayName("Дата")]
public DateTime Date
{
get => _date;
private set
{
_date = value;
OnPropertyChanged(nameof(Date));
}
}
public Product() { }
public Product(int id, string name, int qry, string category, DateTime date)
{
Id = id;
Name = name;
Qry = qry;
Category = category;
Date = date;
}
}
Создаём ObservableObject, которая будет реализовывать INotifyPropertyChanged:
internal class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
Создаём Form1ViewModel (ViewModel):
internal class Form1ViewModel : ObservableObject
{
private BindingList<Product> _products;
public BindingList<Product> Products
{
get => _products ?? new BindingList<Product>();
set
{
_products = value;
OnPropertyChanged(nameof(Products));
}
}
public Form1ViewModel(IEnumerable<Product> products)
{
_products = new BindingList<Product>();
foreach (var product in products)
Products.Add(product);
}
}
Корректируем Form1 (View). Метод CreateTable замените на ваш SQL запрос, после которого остаётся DataTable. Пояснять тут ничего не буду - это крайне легко и, даже если не знаете, загуглить можно:
public partial class Form1 : Form
{
private readonly Form1ViewModel _viewModel;
public Form1()
{
InitializeComponent();
var list = CreateTable().ToEnumerable<Product>();
_viewModel = new Form1ViewModel(list);
dataGridView1.DataBindings.Add(nameof(DataGridView.DataSource), _viewModel, nameof(_viewModel.Products));
}
private DataTable CreateTable()
{
var dt = new DataTable();
dt.Columns.Add("Id");
dt.Columns.Add("Name");
dt.Rows.Add(1, "SomeProduct1");
dt.Rows.Add(2, "SomeProduct2");
return dt;
}
}
internal static class Converter
{
public static IEnumerable<T> ToEnumerable<T>(this DataTable dataTable)
{
var objType = typeof(T);
var properties = objType.GetProperties();
var list = new List<T>();
foreach (var row in dataTable.AsEnumerable())
{
var instance = (T)Convert.ChangeType(Activator.CreateInstance(objType), typeof(T));
foreach (var prop in properties)
{
var index = dataTable.Columns.IndexOf(prop.Name);
if (index < 0)
continue;
var item = row.ItemArray[index];
prop.SetValue(instance, Convert.ChangeType(item, prop.PropertyType));
}
list.Add(instance);
}
return list;
}
}
Результат:
Отображается только 2 строки, которые добавил в методе CreateTable.
Перемещение сделаете сами - удаляете из Products и добавляете в корзину, которую нужно будет по аналогии сделать: так же создаёте ещё одну привязку, описываете класс с корзиной (по аналогии с Product, если это нужно). Таким образом, удаляете из BindingList<Product> Products и добавляете в (вы его сделаете сами) BindingList<ShoppingCard> ShoppingCardProducts

