【问题标题】:Disabling a ComboBox Item based on a CheckBox state基于 CheckBox 状态禁用 ComboBox 项
【发布时间】:2019-07-11 10:48:16
【问题描述】:

我有一个场景,我需要根据 CheckBox 的状态禁用 ComboBox 的特定项目。

我在 ComboBox 中有五个 CheckBox 和五个 Item。

如果未选中 CheckBox1,则应禁用 Item1,这同样适用于所有其他 ComboBox 项。
我尝试使用此代码,但没有成功:

private void ComboBox_SelectNode_DrawItem(object sender, DrawItemEventArgs e)
{
    ComboBox comboBox = (ComboBox)sender;
    if (e.Index == 0)
    {
        if (this.isNode0Disabled)
        {
            e.Graphics.DrawString(this.ComboBox_SelectNode.Items[e.Index].ToString(), this.myFont, Brushes.LightGray, e.Bounds);
        }
        else
        {
            e.DrawBackground();
            e.Graphics.DrawString(this.ComboBox_SelectNode.Items[e.Index].ToString(), this.myFont, Brushes.Black, e.Bounds);
            e.DrawFocusRectangle();
        }
    }

    if (e.Index == 1)
    {
        if (this.isNode1Disabled)
        {
            e.Graphics.DrawString(this.ComboBox_SelectNode.Items[e.Index].ToString(), this.myFont, Brushes.LightGray, e.Bounds);
        }
        else
        {
            e.DrawBackground();
            e.Graphics.DrawString(this.ComboBox_SelectNode.Items[e.Index].ToString(), this.myFont, Brushes.Black, e.Bounds);
            e.DrawFocusRectangle();
        }
    }

    if (e.Index == 2)
    {
        if (this.isNode2Disabled)
        {
            e.Graphics.DrawString(this.ComboBox_SelectNode.Items[e.Index].ToString(), this.myFont, Brushes.LightGray, e.Bounds);
        }
        else
        {
            e.DrawBackground();
            e.Graphics.DrawString(this.ComboBox_SelectNode.Items[e.Index].ToString(), this.myFont, Brushes.Black, e.Bounds);
            e.DrawFocusRectangle();
        }
    }

    if (e.Index == 3)
    {
        if (this.isNode3Disabled)
        {
            e.Graphics.DrawString(this.ComboBox_SelectNode.Items[e.Index].ToString(), this.myFont, Brushes.LightGray, e.Bounds);
        }
        else
        {
            e.DrawBackground();
            e.Graphics.DrawString(this.ComboBox_SelectNode.Items[e.Index].ToString(), this.myFont, Brushes.Black, e.Bounds);
            e.DrawFocusRectangle();
        }
    }

    if (e.Index == 4)
    {
        if (this.isNode4Disabled)
        {
            e.Graphics.DrawString(this.ComboBox_SelectNode.Items[e.Index].ToString(), this.myFont, Brushes.LightGray, e.Bounds);
        }
        else
        {
            e.DrawBackground();
            e.Graphics.DrawString(this.ComboBox_SelectNode.Items[e.Index].ToString(), this.myFont, Brushes.Black, e.Bounds);
            e.DrawFocusRectangle();
        }
    }
}

private void ComboBox_SelectNode_SelectedIndexChanged(object sender, EventArgs e)
{
    if (this.ComboBox_SelectNode.SelectedIndex == 0)
    {
        if (this.isNode0Disabled)
        {
            this.ComboBox_SelectNode.SelectedIndex = -1;
        }
    }

    if (this.ComboBox_SelectNode.SelectedIndex == 1)
    {
        if (this.isNode1Disabled)
        {
            this.ComboBox_SelectNode.SelectedIndex = -1;
        }
    }

    if (this.ComboBox_SelectNode.SelectedIndex == 2)
    {
        if (this.isNode2Disabled)
        {
            this.ComboBox_SelectNode.SelectedIndex = -1;
        }
    }

    if (this.ComboBox_SelectNode.SelectedIndex == 3)
    {
        if (this.isNode3Disabled)
        {
            this.ComboBox_SelectNode.SelectedIndex = -1;
        }
    }

    if (this.ComboBox_SelectNode.SelectedIndex == 4)
    {
        if (this.isNode4Disabled)
        {
            this.ComboBox_SelectNode.SelectedIndex = -1;
        }
    }
}

private void CheckBox_Node0_CheckedChanged(object sender, EventArgs e)
{
    if (this.checkBox_Node0.Checked == true)
    {
        this.isNode0Disabled = false;
    }

    if (this.checkBox_Node0.Checked == false)
    {
        this.isNode0Disabled = true;
    }
}

修改后的代码:

private void ComboBox_SelectNode_DrawItem(object sender, DrawItemEventArgs e)
{
    TextFormatFlags comboTRFlags = TextFormatFlags.Left | TextFormatFlags.VerticalCenter;
    if (e.Index < 0)
    {
        return;
    }

    var combo = sender as ComboBox;
    bool isCheckBoxChecked = this.comboCheckBoxes[e.Index].Checked;
    if (isCheckBoxChecked)
    {
        e.DrawBackground();
    }
    else
    {
        using (var brush = new SolidBrush(combo.BackColor))
        {
            e.Graphics.FillRectangle(brush, e.Bounds);
        }
    }

    string itemText = combo.GetItemText(combo.Items[e.Index]);
    Color textColor = isCheckBoxChecked ? e.ForeColor : SystemColors.GrayText;
    TextRenderer.DrawText(e.Graphics, itemText, combo.Font, e.Bounds, textColor, comboTRFlags);
}

private void ComboBox_SelectNode_MeasureItem(object sender, MeasureItemEventArgs e)
=> e.ItemHeight = this.ComboBox_SelectNode.Font.Height + 4;

并将事件声明如下:

this.ComboBox_SelectNode.DrawItem += new DrawItemEventHandler(ComboBox_SelectNode_DrawItem);
this.ComboBox_SelectNode.MeasureItem += new MeasureItemEventHandler(ComboBox_SelectNode_MeasureItem);

private CheckBox[] comboCheckBoxes;
this.comboCheckBoxes = new[] {this.checkBox_Node0, this.checkBox_Node1, this.checkBox_Node2, this.checkBox_Node3 , this.checkBox_Node4};

但是当我运行应用程序时,这些事件没有触发。

【问题讨论】:

    标签: c# winforms checkbox combobox


    【解决方案1】:

    如果您将 CheckBox 添加到集合中,您可能会让您的生活更轻松(并且代码更易于管理),因此您可以使用 配对组合框项目。
    像这样,使用 CheckBox 控件数组:
    (当然,请根据您的设计调整 CheckBoxes 名称)

    private CheckBox[] comboCheckBoxes;
    public form1()
    {
        InitializeComponent();
        comboCheckBoxes = new[] { chkFirst, chkSecond, chkThird, chkFourth, chkLast};
    }
    

    然后您可以在绘制之前选择每个项目文本的样式。

    我正在使用TextRenderer.DrawText 来绘制项目的文本:使用此方法而不是Graphics.DrawString() 可以正确呈现文本对齐方式。

    TextFormatFlags comboTRFlags = TextFormatFlags.Left | TextFormatFlags.VerticalCenter;
    
    private void comboBox1_DrawItem(object sender, DrawItemEventArgs e)
    {
        if (e.Index < 0) return;
        var combo = sender as ComboBox;
        bool isCheckBoxChecked = comboCheckBoxes[e.Index].Checked;
        if (isCheckBoxChecked) {
            e.DrawBackground();
        }
        else {
            using (var brush = new SolidBrush(combo.BackColor)) {
                e.Graphics.FillRectangle(brush, e.Bounds);
            }
        }
        string itemText = combo.GetItemText(combo.Items[e.Index]);
        Color textColor = isCheckBoxChecked ? e.ForeColor : SystemColors.GrayText;
        TextRenderer.DrawText(e.Graphics, itemText, combo.Font, e.Bounds, textColor, comboTRFlags);
    }
    
    private void comboBox1_MeasureItem(object sender, MeasureItemEventArgs e) 
        => e.ItemHeight = comboBox1.Font.Height + 4;
    
    private void comboBox1_SelectionChangeCommitted(object sender, EventArgs e)
    {
        if (!comboCheckBoxes[comboBox1.SelectedIndex].Checked) {
            comboBox1.SelectedIndex = -1;
            return;
        }
    }
    

    它是这样工作的:

    【讨论】:

      猜你喜欢
      • 2021-12-08
      • 1970-01-01
      • 2014-07-05
      • 1970-01-01
      • 2016-03-04
      • 2013-10-22
      • 1970-01-01
      • 2016-02-29
      • 1970-01-01
      相关资源
      最近更新 更多