2.8 案例分析8 ComboBox控件的综合使用
2.8.1 案例描述
本节介绍常用控件ComboBox的综合使用。
2.8.2 案例分析
ComboBox控件的使用方法。
2.8.3 案例实现与技巧
① 首先,运行Visual Studio 2005,新建一个Windows应用程序,并命名为ComboBoxctl。
② 向设计窗口中的Form1窗体上的适当位置拖曳两个ComboBox控件,分别修改其属性如下表所示:
③ 向设计窗口中的Form1窗体上的适当位置拖曳两个Label控件,分别修改其属性如下表所示:
④ 完成上面步骤后,设计视图中的窗体示例如图2-18所示。
⑤ 向窗体的右侧拖曳一个GroupBox控件,并修改其Text属性为“组合框的使用”。
⑥ 在groupBox1控件里拖放三个ComboBox控件,使其上下整齐排列于groupBox1控件中,如图2-19所示。
图2-18 设计视图中的窗体示例
图2-19 控件布局与设计(一)
⑦ 修改三个ComboBox控件的属性如下表所示:
⑧ 在groupBox1控件里拖放6个Label控件,4个ComboBox控件,一个Panel控件,如图2-20所示。
图2-20 控件布局与设计(二)
⑨ 修改上述控件的属性如下表所示:
⑩ 向groupBox1控件的底部拖曳一个Panel控件,修改其BorderStyle属性为“Fixed3D”。
⑪ 切换到源代码编辑视图,在窗口类中加入以下成员变量并进行初始化。
private Size cmbsize ; private Hashtable brushMap = new Hashtable(); private Color gradientBegin = Color.Red; private Color gradientEnd = Color.Blue;
⑫ 在窗口类的构造函数中加入以下初始化代码,其中的部分方法将在随后实现。
public ComboBoxCtl () { // // Windows 窗体设计器支持所必需的 // InitializeComponent(); InitControlState(); FillItems(comboBegin); FillItems(comboEnd); comboBegin.SelectedIndex = 0; comboEnd.SelectedIndex = comboEnd.Items.Count-1; cmbsize = comboBegin.Size; }
⑬ InitControlState方法的详细内容如下所示:
private void InitControlState() { // 同步复选框 chkSorted.Checked = comboBegin.Sorted; chkEnabled.Checked = comboBegin.Enabled; chkIntegralHeight.Checked = comboBegin.IntegralHeight; // 同步组合框样式与 ComboBoxStyle.DROPDOWN StringIntObject[] aStyle = new StringIntObject[3]; aStyle[0] = new StringIntObject("简单",(int)ComboBoxStyle.Simple); aStyle[1] = new StringIntObject("下拉",(int)ComboBoxStyle.DropDown); aStyle[2] = new StringIntObject("下拉列表",(int)ComboBoxStyle. DropDownList); cmbStyle.Items.AddRange(aStyle); comboBegin.DropDownStyle = (ComboBoxStyle)aStyle[1].i; comboEnd.DropDownStyle = (ComboBoxStyle)aStyle[1].i; cmbStyle.SelectedIndex = 1; // 同步组合框绘制模式与 DrawMode.NORMAL StringIntObject[] aDMO = new StringIntObject[3]; aDMO[0] = new StringIntObject("正常",(int)DrawMode.Normal); aDMO[1] = new StringIntObject("Ownerdrawfixed",(int)DrawMode. OwnerDrawFixed); aDMO[2] = new StringIntObject("Ownerdrawvariable",(int)DrawMode. OwnerDrawVariable); cmbDrawMode.Items.AddRange(aDMO); comboBegin.DrawMode = (DrawMode)aDMO[0].i; comboEnd.DrawMode = (DrawMode)aDMO[0].i; cmbDrawMode.SelectedIndex = 0; }
⑭ 在窗体类中加入下面的成员方法,该方法的作用是将颜色项目加入到ComboBox列表。
private void InitControlState() { // 同步复选框 chkSorted.Checked = comboBegin.Sorted; chkEnabled.Checked = comboBegin.Enabled; chkIntegralHeight.Checked = comboBegin.IntegralHeight; // 同步组合框样式与 ComboBoxStyle.DROPDOWN StringIntObject[] aStyle = new StringIntObject[3]; aStyle[0] = new StringIntObject("简单",(int)ComboBoxStyle.Simple); aStyle[1] = new StringIntObject("下拉",(int)ComboBoxStyle.DropDown); aStyle[2] = new StringIntObject("下拉列表",(int)ComboBoxStyle. DropDownList); cmbStyle.Items.AddRange(aStyle); comboBegin.DropDownStyle = (ComboBoxStyle)aStyle[1].i; comboEnd.DropDownStyle = (ComboBoxStyle)aStyle[1].i; cmbStyle.SelectedIndex = 1; // 同步组合框绘制模式与 DrawMode.NORMAL StringIntObject[] aDMO = new StringIntObject[3]; aDMO[0] = new StringIntObject("正常",(int)DrawMode.Normal); aDMO[1] = new StringIntObject("Ownerdrawfixed",(int)DrawMode. OwnerDrawFixed); aDMO[2] = new StringIntObject("Ownerdrawvariable",(int)DrawMode. OwnerDrawVariable); cmbDrawMode.Items.AddRange(aDMO); comboBegin.DrawMode = (DrawMode)aDMO[0].i; comboEnd.DrawMode = (DrawMode)aDMO[0].i; cmbDrawMode.SelectedIndex = 0; }
⑮ 在窗体类中加入下面的成员方法,该方法的作用是返回组合框中当前选定项的整型值。
private int SelectedValue(ComboBox cmb) { int ret; object obj = cmb.SelectedItem; if (obj == null) { return -1; } try { ret = Int32.Parse(obj.ToString()); } catch (FormatException) { return -1; } return ret; }
⑯ 在窗体类中加入下面的成员方法,该方法的作用是对给定的组合框进行随机无序播放。
private void RandomShuffle(ComboBox cmb) { object[] items = new object[cmb.Items.Count]; cmb.Items.CopyTo(items,0); int swapItem; Random rand = new Random(); for (int i = 0; i < items.Length; ++i) { swapItem = Math.Abs(rand.Next()) % items.Length; if (swapItem != i) { object tempObject = items[swapItem]; items[swapItem] = items[i]; items[i] = tempObject; } } cmb.Items.Clear(); cmb.Items.AddRange(items); }
⑰ 下面开始向程序加入事件处理程序来响应用户的选择。如果组合框为Owner DrawDrawMode,则调用此DrawItem事件处理程序在组合框中绘制项。方法的内容如下所示:
private void combo_DrawItem(object sender,DrawItemEventArgs die) { ComboBox cmb = (ComboBox) sender; if (die.Index == -1) return; if (sender == null) return; //字符串 brushName = (string)cmb.Items[die.Index] //SolidBrush selectedBrush = (SolidBrush)brushMap[brushName] SolidBrush selectedBrush = (SolidBrush)cmb.Items[die.Index]; Graphics g = die.Graphics; // 如果选择了项,则绘制正确的背景颜色 die.DrawBackground(); die.DrawFocusRectangle(); // 绘制颜色的预览框 Rectangle rectPreviewBox = die.Bounds; rectPreviewBox.Offset(2,2); rectPreviewBox.Width = 20; rectPreviewBox.Height -= 4; g.DrawRectangle(new Pen(die.ForeColor),rectPreviewBox); // 获取选定颜色的相应 Brush 对象 // 并填充预览框 rectPreviewBox.Offset(1,1); rectPreviewBox.Width -= 2; rectPreviewBox.Height -= 2; g.FillRectangle(selectedBrush,rectPreviewBox); // 绘制选定颜色的名称 g.DrawString(selectedBrush.Color.ToString(),Font,new SolidBrush(die. ForeColor),die.Bounds.X+30,die.Bounds.Y+1); }
⑱ 响应用户改变的所有方法如下所示,在后面需要将多个事件处理程序分别注册到不用的ComboBox控件上,以完成对用户的响应。
private void chkEnabled_CheckedChanged(object sender,EventArgs e) { comboBegin.Enabled = chkEnabled.Checked; comboEnd.Enabled = chkEnabled.Checked; } private void chkIntegralHeight_CheckedChanged(object sender,EventArgs e) { comboBegin.IntegralHeight = chkIntegralHeight.Checked; comboEnd.IntegralHeight = chkIntegralHeight.Checked; } private void chkSorted_CheckedChanged(object sender,EventArgs e) { bool sorted = chkSorted.Checked; comboBegin.Sorted = sorted; comboEnd.Sorted = sorted; if (!sorted) { RandomShuffle(comboBegin); RandomShuffle(comboEnd); } } private void cmbItemHeight_SelectedIndexChanged(object sender,EventArgs e) { int i = SelectedValue(cmbItemHeight); if (i == -1) return; comboBegin.ItemHeight = i; comboEnd.ItemHeight = i; } private void cmbStyle_SelectedIndexChanged(object sender,EventArgs e) { ComboBoxStyle i = (ComboBoxStyle)(((StringIntObject)cmbStyle. SelectedItem).i); comboBegin.DropDownStyle = i; comboEnd.DropDownStyle = i; if (i == ComboBoxStyle.Simple) { Size cmbsize2 = new Size(cmbsize.Width,cmbsize.Height * 3); comboBegin.Size = cmbsize2; comboEnd.Size = cmbsize2; cmbMaxDropDownItems.Enabled = false; } else { cmbMaxDropDownItems.Enabled = true; } } private void cmbDrawMode_SelectedIndexChanged(object sender,EventArgs e) { DrawMode i = (DrawMode)(((StringIntObject)cmbDrawMode.SelectedItem).i); comboBegin.DrawMode = i; comboEnd.DrawMode = i; if (i == DrawMode.OwnerDrawVariable) { cmbItemHeight.Enabled = true; } else { cmbItemHeight.Enabled = false; } } private void comboBegin_SelectedIndexChanged(object sender,EventArgs e) { if (comboBegin.SelectedIndex >= 0) { SolidBrush b = (SolidBrush)(comboBegin.SelectedItem); gradientBegin = b.Color; panel1.Invalidate(); } } private void comboEnd_SelectedIndexChanged(object sender,EventArgs e) { if (comboBegin.SelectedIndex >= 0) { SolidBrush b = (SolidBrush)(comboEnd.SelectedItem); gradientEnd = b.Color; panel1.Invalidate(); } } private void cmbMaxDropDownItems_SelectedIndexChanged(object sender,EventArgs e) { int i = SelectedValue(cmbMaxDropDownItems); if (i == -1) return; comboBegin.MaxDropDownItems = i; comboEnd.MaxDropDownItems = i; } private void combo_MeasureItem(object sender,MeasureItemEventArgs mie) { ComboBox cb = (ComboBox) sender; mie.ItemHeight = cb.ItemHeight - 2; } private void panel1_Paint(object sender,PaintEventArgs e) { Brush brush = new LinearGradientBrush (panel1.ClientRectangle,gradientBegin,gradientEnd,LinearGradientMode.ForwardDiagonal) ; e.Graphics.FillRectangle(brush,panel1.ClientRectangle); }
⑲ 现在可以切换到设计视图下了,给各个ComboBox控件注册事件处理程序,首先找到窗体左面的两个ComboBox控件,分别为comboBegin和comboEnd;然后为这两个控件注册DrawItem事件的处理程序为combo_DrawItem,这个方法在上面的代码中已经给出了。
⑳ 可以按照下面的列表为ComboBox控件注册事件处理程序。
(21)按照下面的列表为CheckBox注册事件处理程序。
(22)按照下面的列表为控制外观样式的4个ComboBox添加注册事件处理程序。
(23)选择Visual Studio 2005 IDE主菜单“调试”|“开始执行(不调试)”菜单项来运行应用程序。程序运行结果如图2-21所示。
(24)通过控制外观可以显示不同的效果,如图2-22所示。
图2-21 程序运行结果(一)
图2-22 程序运行结果(二)