C# 基于C中的复选框状态禁用组合框项

C# 基于C中的复选框状态禁用组合框项,c#,winforms,checkbox,combobox,C#,Winforms,Checkbox,Combobox,我不熟悉WinC窗体。我有一个场景,需要根据复选框状态禁用组合框的特定项 我有五个复选框,即复选框1、复选框2、复选框3、复选框4、复选框5和组合框中的五个项目,即item1、item2、item3、item4、item5 如果未选中复选框1,则应禁用项目1,并且这同样适用于所有其他组合框项目。我正在尝试这段代码,但没有成功实现我想要的,有人能帮我吗?谢谢 private void ComboBox_SelectNode_DrawItem(object sender, DrawItemEvent

我不熟悉WinC窗体。我有一个场景,需要根据复选框状态禁用组合框的特定项

我有五个复选框,即复选框1、复选框2、复选框3、复选框4、复选框5和组合框中的五个项目,即item1、item2、item3、item4、item5

如果未选中复选框1,则应禁用项目1,并且这同样适用于所有其他组合框项目。我正在尝试这段代码,但没有成功实现我想要的,有人能帮我吗?谢谢

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 CheckBox[] comboCheckBoxes;
public form1()
{
    InitializeComponent();
    comboCheckBoxes = new[] { chkFirst, chkSecond, chkThird, chkFourth, chkLast};
}
然后,可以在绘制每个项目的文本之前选择其样式

我正在使用绘制项目的文本:使用此方法而不是Graphics.DrawString正确呈现文本对齐方式

这就是它的工作原理:


如上所述修改了代码,但在我运行应用程序时,comboBox1\u DrawItem方法未触发。您尚未订阅SelectionChangeCommitted事件。这是必需的。如果仍选择了已更改的索引,请将其删除。事件处理程序名称与您以前使用的名称相同。注意不要订阅两次。组合框DrawMode必须设置为DrawMode.OwnerDrawVariable。在设计器中看到它已设置。将TextFormatFlags comboTRFlags作为字段移动到方法外部:不需要每次调用该方法时都创建局部变量。我看不出您是否也已将复选框分配给ComboCheckBox数组字段。我已更改SelectedIndex中的其他逻辑。所以我不能移除它。也许我可以将该逻辑移到SelectionChangeCommitted?实际上,您可以将SelectionChangeCommitted中的代码移到SelectedIndexChanged中,放在您已有的代码之上。是一样的。您需要添加一个复选框:if[ComboBox]。SelectedIndex<0返回;在其他事情之前。如果事件仍然未引发,则表示您尚未正确连接它,或者未设置ComboBox.DrawMode。然后,您应该使用我在这里发布的代码以干净的形式测试它。您是对的。按照您所说的进行更改后,它现在开始工作。谢谢!
    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};
private CheckBox[] comboCheckBoxes;
public form1()
{
    InitializeComponent();
    comboCheckBoxes = new[] { chkFirst, chkSecond, chkThird, chkFourth, chkLast};
}
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;
    }
}