zoukankan      html  css  js  c++  java
  • 下拉框中带有复选框的OwnerDraw组合框

    介绍 我需要向列表视

      

    图添加筛选。列表视图已经有了一个工具条,我可以在其中添加适当的小部件。我决定使用带有复选框的下拉组合框来打开和关闭项目,这是最节省空间、最直观的实现方式。但是,这需要一个所有者绘制的组合框。幸运的是,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

  • 相关阅读:
    python3 进程间的通信(管道)Pipe
    python3 进程间的通信(队列)Queue
    python3 队列的简单用法Queue
    python3 进程锁Lock(模拟抢票)
    python3 守护进程daemon
    python3 僵尸进程
    python3 process中的name和pid
    python3 Process中的terminate和is_alive
    python3 通过多进程来实现一下同时和多个客户端进行连接通信
    python3 进程之间数据是隔离的
  • 原文地址:https://www.cnblogs.com/Dincat/p/13438122.html
Copyright © 2011-2022 走看看