介绍 我需要向列表视
图添加筛选。列表视图已经有了一个工具条,我可以在其中添加适当的小部件。我决定使用带有复选框的下拉组合框来打开和关闭项目,这是最节省空间、最直观的实现方式。但是,这需要一个所有者绘制的组合框。幸运的是,2.0版本的. net框架包含了一个助手类CheckBoxRenderer,如果提供正确的参数,它将为您将复选框呈现到下拉列表中。 使用的代码 第一步是子类化System.Windows.Forms。组合框类: 隐藏,复制Code
public partial class CheckComboBox : ComboBox { public CheckComboBox() { this.DrawMode = DrawMode.OwnerDrawFixed; ... } ... }
注意,我设置了DrawMode属性来告诉ComboBox我们打算自己呈现下拉列表项。下一步是定义一个类来包含下拉列表项数据并维护状态。这是一个简单的类: 隐藏,收缩,复制Code
public class CheckComboBoxItem { public CheckComboBoxItem( string text, bool initialCheckState ) { _checkState = initialCheckState; _text = text; } private bool _checkState = false; public bool CheckState { get { return _checkState; } set { _checkState = value; } } private string _text = ""; public string Text { get { return _text; } set { _text = value; } } public override string ToString() { return "Select Options"; } }
然后我们连接一个委托到ComboBox的DrawItem事件: 隐藏,复制Code
this.DrawItem += new DrawItemEventHandler(CheckComboBox_DrawItem);
并实施如下: 隐藏,收缩,复制Code
void CheckComboBox_DrawItem( object sender, DrawItemEventArgs e ) { if (e.Index == -1) { return; } if( !( Items[ e.Index ] is CheckComboBoxItem ) ) { e.Graphics.DrawString( Items[ e.Index ].ToString(), this.Font, Brushes.Black, new Point( e.Bounds.X, e.Bounds.Y ) ); return; } CheckComboBoxItem box = (CheckComboBoxItem)Items[ e.Index ]; CheckBoxRenderer.RenderMatchingApplicationState = true; CheckBoxRenderer.DrawCheckBox( e.Graphics, new Point( e.Bounds.X, e.Bounds.Y ), e.Bounds, box.Text, this.Font, ( e.State & DrawItemState.Focus ) == 0, box.CheckState ? CheckBoxState.CheckedNormal : CheckBoxState.UncheckedNormal ); }
在这个委托中,我们要做的第一件事是验证我们呈现的项是否作为CheckComboBoxItem添加。如果不是,我们将其呈现为一个简单的字符串。否则,我们将从Items集合中(使用DrawItemEventArgs)获得适当的CheckComboBoxItem。索引属性)。然后调用CheckBoxRenderer.DrawCheckBox()方法,传入我们想要呈现复选框的图形对象以及位置、大小、文本、字体、焦点和检查状态。 结果是,它将使我们的下拉列表项看起来像复选框: 接下来,我们想在选中其中一个项目时切换检查状态。我们连接另一个委托,但这次是selectedindexchangeevent 隐藏,复制Code
this.SelectedIndexChanged += new EventHandler( CheckComboBox_SelectedIndexChanged );
并实施如下: 隐藏,复制Code
void CheckComboBox_SelectedIndexChanged( object sender, EventArgs e ) { CheckComboBoxItem item = (CheckComboBoxItem)SelectedItem; item.CheckState = !item.CheckState; ... }
这允许我们切换下拉框中的复选框,但不允许该控件的用户知道发生了什么事情。因此,我们还添加了一个公共事件,以通知控件的用户在下拉列表中某个项的检查状态发生变化: 隐藏,复制Code
public event EventHandler CheckStateChanged;
当我们切换上面的状态时,我们触发了这个事件,所以完整的方法是这样的: 隐藏,复制Code
void CheckComboBox_SelectedIndexChanged( object sender, EventArgs e ) { CheckComboBoxItem item = (CheckComboBoxItem)SelectedItem; item.CheckState = !item.CheckState; if (CheckStateChanged != null) CheckStateChanged(item, e); }
使用控制 要使用这个控件,你只需将它添加到你选择的容器中,然后像这样添加项目: 隐藏,复制Code
checkComboBox1.Items.Add(new CheckComboBox.CheckComboBoxItem("One", true)); checkComboBox1.Items.Add(new CheckComboBox.CheckComboBoxItem("Two", true)); checkComboBox1.Items.Add(new CheckComboBox.CheckComboBoxItem("Three", true));
要获得用户更改检查状态的通知: 隐藏,复制Code
this.checkComboBox1.CheckStateChanged += new EventHandler(this.checkComboBox1_CheckStateChanged);
可以这样处理: 隐藏,复制Code
private void checkComboBox1_CheckStateChanged(object sender, EventArgs e) { if (sender is CheckComboBox.CheckComboBoxItem) { CheckComboBox.CheckComboBoxItem item = (CheckComboBox.CheckComboBoxItem)sender; ... } }
完成的示例应用程序。 下拉。 的兴趣点 有一个烦恼,我相信肯定有比我想到的更好的解决办法。我想要的文本框部分的控制,以包含固定的文本和不可编辑。因此,作为一个权宜之计,我将它初始化为字符串“Select Options”,并覆盖CheckComboBoxItem类的ToString()方法,以始终返回相同的字符串。这样,无论用户最后选择哪一项,字符串都不会改变。这并没有使它不可编辑。 如果时间允许,我想做许多补充: 正确地对齐文本对齐(需要找出如何计算复选框位图的宽度为此正确)添加“选择所有”和“选择”项分离器顶部的下拉允许其他控件类型下拉(例如-单选按钮) 历史 2007年5月24日:原版本已上载 本文转载于:http://www.diyabc.com/frontweb/news346.html