從 Database 中把 DataTable 後,把重覆值去除掉後當成 comboBox 資料來源,希望點選 comboxBox 時,可以顯示該選項在 DataTable 內的資料筆數想法是利用 T-SQL DISTINCT 語法找出唯一値當成 comboxBox 資料來源,再根據使用者點選資料,進入 Database 計算資料筆數,論壇討論則是把資料通通抓到 C# 中來處理,剛好拿來練習 ADO.NET
namespace ComboBoxSearch
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
// dtCombo 為全域變數
DataTable dtCombo = new DataTable("Demo");
private void Form1_Load(object sender, EventArgs e)
{
// 資料來源建立
sourceFill();
// 設定 ComboBox 的 DropDownStyle
cboList.DropDownStyle = ComboBoxStyle.DropDownList;
cboDataTable.DropDownStyle = ComboBoxStyle.DropDownList;
// 設定 ComboBox 一開始不顯示任何選項
cboList.SelectedIndex = -1;
cboDataTable.SelectedIndex = -1;
// 不允許 DataGridView 可以新增資料
gvData.AllowUserToAddRows = false;
}
private void sourceFill()
{
// dtCombo Schema 和 Data 建立
dtCombo.Columns.Add("ColName",typeof(string));
dtCombo.Rows.Add("A");
dtCombo.Rows.Add("A");
dtCombo.Rows.Add("A");
dtCombo.Rows.Add("B");
dtCombo.Rows.Add("B");
dtCombo.Rows.Add("C");
dtCombo.Rows.Add("C");
dtCombo.Rows.Add("C");
dtCombo.Rows.Add("C");
dtCombo.Rows.Add("D");
dtCombo.Rows.Add("D");
dtCombo.Rows.Add("D");
dtCombo.Rows.Add("D");
dtCombo.Rows.Add("D");
// 資料來源為 List
List<string> uniqueLINQ = dtCombo.AsEnumerable().Select(row => row.Field<string>("ColName")).Distinct().ToList();
cboList.DataSource = uniqueLINQ;
// 資料來源為 DataTable
DataTable uniqueDataTable = dtCombo.DefaultView.ToTable(true, "ColName");
cboDataTable.DataSource = uniqueDataTable;
cboDataTable.ValueMember = "ColName";
cboDataTable.DisplayMember = "ColName";
// 把 dtCombo 資料顯示出來,方便比對資料
gvData.DataSource = dtCombo;
}
private void gvData_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (!gvData.Columns[e.ColumnIndex].Name.Equals("ColName")) return;
string item =
cboList.SelectedIndex == -1
? string.Empty
: cboList.SelectedItem.ToString();
string value =
cboDataTable.SelectedIndex == -1
? string.Empty
: cboDataTable.SelectedValue.ToString();
e.CellStyle.BackColor = SystemColors.Control;
if (e.Value.ToString() == item || e.Value.ToString() == value)
e.CellStyle.BackColor = Color.LightGray;
}
private void cboList_SelectionChangeCommitted(object sender, EventArgs e)
{
// LINQ 作法
if (cboList.SelectedIndex == -1) return;
string item = cboList.SelectedItem.ToString();
string result = dtCombo.AsEnumerable().Where(row => row.Field<string>("ColName") == item).Count().ToString();
txtList.Text = result;
gvData.Refresh();
}
private void cboDataTable_SelectionChangeCommitted(object sender, EventArgs e)
{
// ADO.NET 作法
if (cboDataTable.SelectedIndex == -1) return;
string value = cboDataTable.SelectedValue.ToString();
string filter = string.Format("ColName = '{0}'", value);
string result = dtCombo.Compute("COUNT(ColName)", filter).ToString();
txtDataTable.Text = result;
gvData.Refresh();
}
}
}
練習時發現,當 Form 一執行時都會觸發 ComboBox SelectedIndexChanged 事件,在 MSDN ComboBox.SelectionChangeCommitted 事件,看見這段說明
只有當使用者變更下拉式方塊選擇時,才會引發 SelectionChangeCommitted。 請勿使用 SelectedIndexChanged 或 SelectedValueChanged 來擷取使用者變更,因為當以程式方式變更選擇時,也會引發這些事件。ComboBox 預設點擊事件為 SelectedIndexChanged,所以也就很直覺地把 Code 寫在裡面,Orz ~~
沒有留言:
張貼留言