摘要:DataGridView的ComboBox型的欄位不能異動DataSource的替代方式,和練習DataRelation
替代方式的執行畫面如下:
資料庫是NORTHWND,
當點到ProductName欄位時在Form右邊出現關聯該列CtegoryName欄位的ProductName選項們,
使用者可點選ProductName選項替換掉選取的ProductName欄位
沒有點選ProductName欄位或CategoryName欄位的Value無值時,隱藏ProductName選項們
這個Form除了將DataGridView,ListBox,SplitContainer拉進Form裡作以下的畫面配置外,
其餘的屬性,事件,宣告等...都寫在.cs檔裡,除了我自己練習外也可讓您清楚所有的設定。
程式如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
namespace WindowsFormsApplication1
{
public partial class Form3 : Form
{
public Form3()
{
InitializeComponent();
}
DataSet DataSet_1;
BindingSource BindingSource_Category;
BindingSource BindingSource_Product;
private void Form3_Load(object sender, EventArgs e)
{
# region 建立一個DataSet然後加入DataTable_Categories,DataTable_Products資料表並填入資料
DataTable DataTable_OrderDetails = new DataTable("DataTable_OrderDetails");
DataTable DataTable_Categories = new DataTable("DataTable_Categories");
DataTable DataTable_Products = new DataTable("DataTable_Products");
DataSet_1 = new DataSet();
DataSet_1.Tables.AddRange(new DataTable[] { DataTable_OrderDetails, DataTable_Categories, DataTable_Products });
using (SqlConnection SqlConnection_1 = new SqlConnection(WindowsFormsApplication1.Properties.Settings.Default.NORTHWNDConnectionString))
{
using (SqlCommand SqlCommand_1 = new SqlCommand())
{
SqlCommand_1.Connection = SqlConnection_1;
using (SqlDataAdapter SqlDataAdapter_1 = new SqlDataAdapter(SqlCommand_1))
{
SqlCommand_1.CommandText =
" SELECT top 15 [Order Details].OrderID, Categories.CategoryID, [Order Details].ProductID, Products.ProductName, "
+ " [Order Details].UnitPrice, [Order Details].Quantity, [Order Details].Discount "
+ " FROM [Order Details] INNER JOIN "
+ " Products ON [Order Details].ProductID = Products.ProductID INNER JOIN "
+ " Categories ON Products.CategoryID = Categories.CategoryID ";
SqlDataAdapter_1.Fill(DataSet_1, "DataTable_OrderDetails");
SqlCommand_1.CommandText = "select CategoryID,CategoryName from Categories";
SqlDataAdapter_1.Fill(DataSet_1, "DataTable_Categories");
SqlCommand_1.CommandText = "select ProductID,ProductName,CategoryID from Products";
SqlDataAdapter_1.Fill(DataSet_1, "DataTable_Products");
}
}
}
#endregion
#region 建立DataTable_Categories,DataTable_Products資料表間的關聯,並將控制項綁定資料
DataRelation DataRelation_1 = new DataRelation("FK_Products_Categories", DataTable_Categories.Columns["CategoryID"], DataTable_Products.Columns["CategoryID"]);
DataSet_1.Relations.Add(DataRelation_1);
BindingSource_Category = new BindingSource(DataSet_1, "DataTable_Categories");
BindingSource_Product = new BindingSource(BindingSource_Category, "FK_Products_Categories");
#region 建立一個要放在dataGridView1裡的ComboBox型的資料行,換掉dataGridView1設定DataSource後自動產生的CategoryID資料行
DataGridViewComboBoxColumn categoryNameDataGridViewComboBoxColumn = new DataGridViewComboBoxColumn();
categoryNameDataGridViewComboBoxColumn.Name = "CategoryID";
categoryNameDataGridViewComboBoxColumn.DataSource = BindingSource_Category;
categoryNameDataGridViewComboBoxColumn.ValueMember = "CategoryID";
categoryNameDataGridViewComboBoxColumn.DisplayMember = "CategoryName";
categoryNameDataGridViewComboBoxColumn.DataPropertyName = "CategoryID";
categoryNameDataGridViewComboBoxColumn.HeaderText = "CategoryName";
dataGridView1.DataSource = DataSet_1.Tables["DataTable_OrderDetails"];
dataGridView1.Columns.Remove("CategoryID");
dataGridView1.Columns.Insert(dataGridView1.Columns["OrderID"].Index + 1, categoryNameDataGridViewComboBoxColumn);
#endregion
listBox1.DataSource = BindingSource_Product;
listBox1.ValueMember = "ProductID";
listBox1.DisplayMember = "ProductName";
#endregion
#region 加入操作時的事件
dataGridView1.CellEnter += new DataGridViewCellEventHandler(dataGridView1_CellEnter);
listBox1.Click += new EventHandler(listBox1_Click);
#endregion
#region 設定一些外觀
dataGridView1.Columns["OrderID"].ReadOnly = true;
dataGridView1.Columns["ProductID"].ReadOnly = true;
dataGridView1.Columns["ProductName"].ReadOnly = true;
this.WindowState = FormWindowState.Maximized;
splitContainer1.Dock = DockStyle.Fill;
dataGridView1.Dock = DockStyle.Fill;
listBox1.Dock = DockStyle.Fill;
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
#endregion
}
void listBox1_Click(object sender, EventArgs e)
{
#region 將使用者在listBox1選的Product填入在dataGridView1指定的Product欄位
dataGridView1.CurrentRow.Cells["ProductID"].Value = ((DataRowView)listBox1.SelectedItem).Row[0];
dataGridView1.CurrentRow.Cells["ProductName"].Value = ((DataRowView)listBox1.SelectedItem).Row[1];
#endregion
}
void dataGridView1_CellEnter(object sender, DataGridViewCellEventArgs e)
{
#region 若使用者點的不是dataGridView1的Product欄位則將splitContainer1.Panel2收起來,若是則展開並顯示所選的Category的Products
if (e.ColumnIndex == dataGridView1.Columns["ProductName"].Index && !string.IsNullOrEmpty(dataGridView1.CurrentRow.Cells["CategoryID"].Value.ToString()))
{
int FindPosition = BindingSource_Category.Find("CategoryID", dataGridView1.CurrentRow.Cells["CategoryID"].Value);
BindingSource_Category.Position = FindPosition;
splitContainer1.Panel2Collapsed = false;
}
else
{
splitContainer1.Panel2Collapsed = true;
}
#endregion
}
}
}
如有更好的方式,懇請您指教~