是否已不滿足Combobox的一成不變的沒有表頭的datasource,是否想打造一個有表頭的呢?follow me!最終效果圖如下﹕
為了實現如上效果圖﹐讓我們一步一步來實現﹕
Step1:
打開VS.net2003建立一個Windows程序﹐將自動生成的Form1改成FrmTest﹐這一步比較簡單﹐沒什么好說。next
Step2:
新加一個WinForm﹐設名為﹕frmDropDownDetail,這個就是我們將要用來填充數據的Form載體啦。定義一個DataGrid﹐并將該DataGrid屬性公開化。設置窗體不顯示在任務欄中﹐以便運行是不會在任務欄上露出不快。
為了實現如上效果圖﹐讓我們一步一步來實現﹕
Step1:
打開VS.net2003建立一個Windows程序﹐將自動生成的Form1改成FrmTest﹐這一步比較簡單﹐沒什么好說。next
Step2:
新加一個WinForm﹐設名為﹕frmDropDownDetail,這個就是我們將要用來填充數據的Form載體啦。定義一個DataGrid﹐并將該DataGrid屬性公開化。設置窗體不顯示在任務欄中﹐以便運行是不會在任務欄上露出不快。
private DataGrid dataGrid;
public DataGrid DataGrid
{
get {return dataGrid;}
set {dataGrid=value;}
}
private int index;
public int Index
{
get {return index;}
set {index=value;}
}
private int mywidth;
public int MyWidth
{
get{return mywidth;}
set{mywidth = value;}
}
public DataGrid DataGrid
{
get {return dataGrid;}
set {dataGrid=value;}
}
private int index;
public int Index
{
get {return index;}
set {index=value;}
}
private int mywidth;
public int MyWidth
{
get{return mywidth;}
set{mywidth = value;}
}
以這些屬性可根據自己需要另行擴展﹐我簡要說明上面几個屬性的作用. DataGrid就不用說了﹐一看就明了﹐是用來承載數據用的。Index是返回當我們雙擊dataGrid時返回第几列的值 的。MyWidth就是返回該WinForm的Width了。
在建構函數中加入如下代碼﹕
this.FormBorderStyle=FormBorderStyle.None;
this.StartPosition=FormStartPosition.Manual;
this.ShowInTaskbar = false;
dataGrid=new DataGrid();
this.Controls.Add(dataGrid);
dataGrid.Dock=DockStyle.Fill;
dataGrid.CaptionVisible=false;
dataGrid.PreferredColumnWidth = 75;
dataGrid.ReadOnly = true;
dataGrid.MouseUp +=new MouseEventHandler(dataGrid_MouseUp);
this.StartPosition=FormStartPosition.Manual;
this.ShowInTaskbar = false;
dataGrid=new DataGrid();
this.Controls.Add(dataGrid);
dataGrid.Dock=DockStyle.Fill;
dataGrid.CaptionVisible=false;
dataGrid.PreferredColumnWidth = 75;
dataGrid.ReadOnly = true;
dataGrid.MouseUp +=new MouseEventHandler(dataGrid_MouseUp);
當然﹐你也可以直接在設計階段將設計好以利用設計工具來自動生成該段代碼。自然而然﹐你看到的你所定義的MouseUp事件的代碼如下﹕
private void dataGrid_MouseUp(object sender, MouseEventArgs e)
{
System.Drawing.Point pt = new System.Drawing. Point(e.X,e.Y);
DataGrid.HitTestInfo hti = (sender as DataGrid).HitTest(pt);
if(hti.Type == DataGrid.HitTestType.Cell)
{
(sender as DataGrid).Select(hti.Row);
this.index = hti.Column;
}
}
{
System.Drawing.Point pt = new System.Drawing. Point(e.X,e.Y);
DataGrid.HitTestInfo hti = (sender as DataGrid).HitTest(pt);
if(hti.Type == DataGrid.HitTestType.Cell)
{
(sender as DataGrid).Select(hti.Row);
this.index = hti.Column;
}
}
以上就完成一個可以其自身加入combobox的下卷中的Winform了。接下來就是使用測試了。
Step3:
重新回到剛剛的FrmTest來。打開檢視代碼并定義如下變量常量﹕
private System.Windows.Forms.ComboBox cbxSource;
private System.Windows.Forms.Label lblSource;
private SqlConnection sqlConn = null;
private SqlDataAdapter sqlDa = null;
private DataSet ds = null;
private frmDropDownDetail frm;
const int WM_KEYUP=0x101;
const int Index = 0;
private System.Windows.Forms.Label lblSource;
private SqlConnection sqlConn = null;
private SqlDataAdapter sqlDa = null;
private DataSet ds = null;
private frmDropDownDetail frm;
const int WM_KEYUP=0x101;
const int Index = 0;
加入Load事件﹕
try
{
frm = new frmDropDownDetail();
frm.Activated +=new EventHandler(frm_Activated);
frm.Deactivate +=new EventHandler(frm_Deactivate);
frm.DataGrid.Click +=new EventHandler(DataGrid_Click);
sqlConn = new SqlConnection("workstation id='KingNa';packet size=4096;user id=sa;password =;data source='localhost';persist security info=False;initial catalog=NorthWind");
string strSql = "SELECT ProductID AS [產品編號] , ProductName AS[產品名稱] , QuantityPerUnit AS [產品包裝],UnitPrice AS [單價] FROM Products";
sqlDa = new SqlDataAdapter();
ds = new DataSet();
sqlDa .SelectCommand = new SqlCommand(strSql,sqlConn);
sqlDa.Fill(ds,"Products");
frm.DataGrid.DataSource=ds;//設置下拉清單的資料源
frm.DataGrid.DataMember="Products";
}
catch(Exception E){MessageBox.Show(E.ToString());}
{
frm = new frmDropDownDetail();
frm.Activated +=new EventHandler(frm_Activated);
frm.Deactivate +=new EventHandler(frm_Deactivate);
frm.DataGrid.Click +=new EventHandler(DataGrid_Click);
sqlConn = new SqlConnection("workstation id='KingNa';packet size=4096;user id=sa;password =;data source='localhost';persist security info=False;initial catalog=NorthWind");
string strSql = "SELECT ProductID AS [產品編號] , ProductName AS[產品名稱] , QuantityPerUnit AS [產品包裝],UnitPrice AS [單價] FROM Products";
sqlDa = new SqlDataAdapter();
ds = new DataSet();
sqlDa .SelectCommand = new SqlCommand(strSql,sqlConn);
sqlDa.Fill(ds,"Products");
frm.DataGrid.DataSource=ds;//設置下拉清單的資料源
frm.DataGrid.DataMember="Products";
}
catch(Exception E){MessageBox.Show(E.ToString());}
自定義几個事件的代碼如下﹕
protected override void WndProc(ref Message m)
{
if (m.Msg==WM_KEYUP)
return;
base.WndProc (ref m);
}
private void frm_Activated(object sender, EventArgs e)
{
frm.Width = this.cbxSource .Width;
}
private void frm_Deactivate(object sender, EventArgs e)
{
frm.Hide();
}
{
BindingManagerBase cm = frm.BindingContext[frm.DataGrid.DataSource,frm.DataGrid.DataMember];
this.cbxSource.Text=((System.Data.DataRowView)cm.Current)[Index].ToString();
frm.Hide();
}
{
frm.Left = cbxSource.PointToScreen(new Point(0,cbxSource.Height)).X;
frm.Top = cbxSource.PointToScreen(new Point(0,cbxSource.Height)).Y;
frm.MyWidth = (sender as ComboBox).Width;
frm.Show();
frm.BringToFront();
}
{
if (m.Msg==WM_KEYUP)
return;
base.WndProc (ref m);
}
private void frm_Activated(object sender, EventArgs e)
{
frm.Width = this.cbxSource .Width;
}
private void frm_Deactivate(object sender, EventArgs e)
{
frm.Hide();
}
private void DataGrid_Click(object sender, EventArgs e)
{
BindingManagerBase cm = frm.BindingContext[frm.DataGrid.DataSource,frm.DataGrid.DataMember];
this.cbxSource.Text=((System.Data.DataRowView)cm.Current)[Index].ToString();
frm.Hide();
}
private void cbx_DropDown(object sender, System.EventArgs e)
{
frm.Left = cbxSource.PointToScreen(new Point(0,cbxSource.Height)).X;
frm.Top = cbxSource.PointToScreen(new Point(0,cbxSource.Height)).Y;
frm.MyWidth = (sender as ComboBox).Width;
frm.Show();
frm.BringToFront();
}
解釋一下WM_KEYUP是為屏蔽用戶用鍵盤時關閉frmDropDownDetail窗體。
至此﹐我們的combobox加載數據表的功能基本實現﹗各位可自行擴展。如果需要源碼的朋碼請與我聯系jinliangliu#163.com﹐有更好實現的朋友也請不吝指教!
當然﹐dudu認為放在首頁不合適﹐請隨意移走﹗畢竟這個沒多少技朮含量!