![](/img/trans.png)
[英]Transfer selected DataGridView row to a new DataGridView in another form
[英]transfer selected datagridview row with image to another datagridview
我正在嘗試制作購物車,當用戶在產品表中選擇行時,輸入數量並單擊“添加到購物車”,該行將轉到購物車表。 我可以做到,但圖像列顯示圖像的 system.byte 讀取。 此外,當我選擇新產品並將新產品添加到購物車時,購物車表中的前一行被覆蓋而不是添加新產品。
public partial class AddToCartForm : Form
{
public AddToCartForm()
{
InitializeComponent();
}
private void AddToCartForm_Load(object sender, EventArgs e)
{
PopulateProductImageDgv("Select * from ProductDetailsTwo", ref dataGridView1);
dataGridView1.MultiSelect = false;
dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView2.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
dataGridView2.RowTemplate.Height = 100;
dataGridView2.AllowUserToAddRows = false;
}
private void btnSaveToCart_Click(object sender, EventArgs e)
{
if (dataGridView1.SelectedRows.Count > 0)
{
DataTable dt = new DataTable();
dt.Columns.Add("Id");
dt.Columns.Add("Name");
dt.Columns.Add("ImageData");
dt.Columns.Add("Qty");
foreach (DataGridViewRow dgvRow in dataGridView1.SelectedRows)
{
dt.Rows.Add(dgvRow.Cells[0].Value, dgvRow.Cells[1].Value, dgvRow.Cells[2].Value, txtqty.Text.ToString());
}
dataGridView2.DataSource = dt;
}
else
{
MessageBox.Show("select something");
}
}
public void PopulateProductImageDgv(string sql, ref DataGridView dg)
{
using (SqlConnection connection = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["cn"].ConnectionString))
{
connection.Open();
using (SqlCommand cmd = new SqlCommand(sql, connection))
{
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable table = new DataTable();
//settings for dgv with image
dg.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
dg.RowTemplate.Height = 100;
dg.AllowUserToAddRows = false;
da.Fill(table);
dg.DataSource = table;
DataGridViewImageColumn imageColumn = new DataGridViewImageColumn();
imageColumn = (DataGridViewImageColumn)dg.Columns[2];
imageColumn.ImageLayout = DataGridViewImageCellLayout.Stretch;
connection.Close();
}
}
}
}
但是,為了簡單起見,我有幾個問題,一個問題是似乎沒有必要在用戶每次單擊“保存到購物車”按鈕時為第二個(選定項目)網格“重新創建”一個新的DataTable
。
此外,發布的代碼只是“覆蓋”了“選定”項目網格中的現有數據。 這是一種奇怪的行為。 例如,用戶單擊一個項目,然后單擊保存到購物車按鈕。 這會將項目保存在所選項目網格中,然后用戶單擊不同的項目,然后單擊保存按鈕……然后,使用已發布的項目,先前保存的項目將消失。 我猜你不想要這種行為。
鑒於上述評論和有限的發布代碼,我建議使用兩個不同的DataTables
的簡單解決方案。 一張表保存“所有”項目,供用戶選擇。 顯然,它開始時填充了所有項目。 第二個表是一個“空”表,用於保存用戶選擇的項目。
我們顯然可以“手動”創建選定項目表,但是,這需要更多的工作,我們需要確保維護某些列。 “克隆”第一個表將有助於查找行並將行從一個表復制到另一個表。 換句話說,我們希望能夠查看“已選擇”項目表並查看當前選擇的項目是否已經在其中。 如果是,我們不想添加新行,我們只想更新現有選定項目的數量。
鑒於此,第二個表的模式可以使用與第一個表相同的模式,只顯示我們想要的列,或者在這種情況下……“添加”一個新的數量列。 如果我們Clone
第一個表模式,然后向其中添加“數量”列,那么搜索和復制將容易得多。 這將起作用,您可以在不手動將列添加到網格的情況下執行此操作。 這意味着即使我們向第二個表添加了另一列,行導入仍然會成功。
下面是一個完整的例子,測試數據使用一個原始表格,每單位包含“ItemID”、“Description”和“Cost”列。 第二個表也有這些列和兩個附加列“QTY”用於數量和“TotalCost”。 “TotalCost”列是一個“Expression”列,它只是將“QTY”值乘以“Cost”值。 “總成本”值將在每次單擊按鈕時“數量”值發生變化時自動更新。 網格的前兩個全局數據表......
DataTable AllItems;
DataTable SelectedItems;
當表單加載時,我們用AllItems
中的所有項目填充AllItems
。 然后我們將這個表模式“克隆”到SelectedItems
表。 然后我們將數量列添加到SelectedItems
表中。 最后將每個網格設置為正確的DataSource
。 就像是…
private void Form3_Load(object sender, EventArgs e) {
AllItems = GetDataFromDB();
SelectedItems = AllItems.Clone();
DataColumn qtyCol = new DataColumn();
qtyCol.ColumnName = "QTY";
qtyCol.DataType = typeof(int);
SelectedItems.Columns.Add(qtyCol);
DataColumn totCol = new DataColumn();
totCol.ColumnName = "Tot";
totCol.DataType = typeof(decimal);
totCol.Expression = "Cost * QTY";
SelectedItems.Columns.Add(totCol);
//SetSelectedItemsGridColumns();
dataGridView1.DataSource = AllItems;
dataGridView2.DataSource = SelectedItems;
}
如果需要,注釋掉的“SetSelectedItemsGridColumns”代碼用於自定義第二個網格的列。
有了這個設置,現在將所有項目的網格中的選定行“復制”到包含選定項目的網格中應該相對簡單。 應該注意的是,無論我們要搜索/查找的字段,都必須與數據庫中的字段類型匹配。 如果您遇到“類型”不匹配錯誤,請檢查以確保代碼中定義的“類型”與數據庫中的“類型”匹配。 在下面的示例中,我使用int
的“類型”來唯一標識數據庫中的每個“ItemID”。 這對您來說顯然/可能會有所不同,您需要更改代碼以匹配您要使用的正確類型/名稱。
一、三個變量: newItemID
唯一標識選中的項目。 和dataRow
用來自每個選定行的數據初始化。 它用於在SelectedItems
表中查找行並更新現有行。 最后一個DataRowView
從第一個網格中抓取所有項目的行。
通過所選行的簡單循環。 抓取選定的行並獲取其唯一的項目 ID。 從數量文本框中解析數量值。 嘗試從所選項目表中獲取行。 如果返回的行為空,則該項目不在表中,我們需要將其添加為新行。 如果返回了一行,那么我們只想將“數量”值添加到現有行中。
private void button1_Click(object sender, EventArgs e) {
int newItemID;
DataRow dataRow;
DataRowView drv;
foreach (DataGridViewRow dgr in dataGridView1.SelectedRows) {
drv = (DataRowView)dgr.DataBoundItem;
newItemID = (int)drv["ItemID"];
int.TryParse(txtQTY.Text.Trim(), out int qty);
dataRow = SelectedItems.AsEnumerable().Where(x => x.Field<int>("ItemID") == newItemID).FirstOrDefault();
if (dataRow != null) {
int tot = (int)dataRow["QTY"] + qty;
dataRow["QTY"] = tot;
}
else {
SelectedItems.ImportRow(drv.Row);
dataRow = SelectedItems.AsEnumerable().Where(x => x.Field<int>("ItemID") == newItemID).FirstOrDefault();
dataRow["QTY"] = qty;
}
}
}
private DataTable GetDataFromDB() {
DataTable dt = new DataTable();
dt.Columns.Add("ItemID", typeof(int));
dt.Columns.Add("Description", typeof(string));
dt.Columns.Add("Cost", typeof(decimal));
Random rand = new Random();
for (int i = 1; i < 10; i++) {
dt.Rows.Add(i, "Item_" + i, rand.NextDouble() * 100);
}
return dt;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.