C# Windows窗体-如何在C中的组合框项中添加不可选的标题?

C# Windows窗体-如何在C中的组合框项中添加不可选的标题?,c#,winforms,combobox,C#,Winforms,Combobox,我需要创建一个自定义组合框控件,允许标题作为分隔符,不应该使用鼠标移动或按键选择 例如: Header1 item1 item2 item3 Header2 item4 item5 我尝试了许多解决方案,但都没有成功。提前谢谢 试试这个自定义组合框。它会忽略标题,但标题的绘制与任何其他项目完全相同,并且当您选择子项目时,它将包含这些额外的空格。但希望这能把你引向正确的方向 public class CustomComboBox : ComboBox { int cu

我需要创建一个自定义组合框控件,允许标题作为分隔符,不应该使用鼠标移动或按键选择

例如:

Header1
  item1
  item2
  item3
Header2
  item4
  item5

我尝试了许多解决方案,但都没有成功。提前谢谢

试试这个自定义组合框。它会忽略标题,但标题的绘制与任何其他项目完全相同,并且当您选择子项目时,它将包含这些额外的空格。但希望这能把你引向正确的方向

public class CustomComboBox : ComboBox
{
    int currentlySelectedIndex = -1;

    protected override void OnSelectionChangeCommitted(EventArgs e)
    {
        if (this.SelectedIndex != -1)
        {
            // Check if we shouldn ignore it:
            object currentlySelectedItem = this.Items[this.SelectedIndex];

            if (ShouldIgnore(currentlySelectedItem))
            {
                Console.WriteLine("Ignoring it! Resetting the index.");

                this.SelectedIndex = currentlySelectedIndex;
            }
        }

        base.OnSelectionChangeCommitted(e);
    }

    protected virtual bool ShouldIgnore(object selectedItem)
    {
        // This is a category if it starts with a space. 
        return !selectedItem.ToString().StartsWith(" ");     
    }

    protected override void OnDropDown(EventArgs e)
    {
        // Save the current index when the drop down shows:
        currentlySelectedIndex = this.SelectedIndex;

        base.OnDropDown(e);
    }
}

再一次,WPF可以轻松地提供解决方案,这些解决方案需要在winforms中进行大量可怕的黑客攻击

将我的代码复制并粘贴到Visual Studio中的文件->新建项目->WPF应用程序中

您很快就会注意到,我的解决方案不仅为标题项提供了不同的视觉外观,而且还防止了不必要的选择,无论是通过鼠标还是键盘,而且不需要对常规ComboBox类进行子类化,这将导致可维护性降低

XAML:

代码隐藏:

using System.Collections.Generic;
using System.Windows;

namespace WpfApplication5
{
    public partial class Window2 : Window
    {
        public Window2()
        {
            InitializeComponent();

            var list = new List<ComboBoxItem>
                {
                    new ComboBoxItem {DisplayText = "Header1", IsHeader = true},
                    new ComboBoxItem {DisplayText = "Item1", IsHeader = false},
                    new ComboBoxItem {DisplayText = "Item2", IsHeader = false},
                    new ComboBoxItem {DisplayText = "Item3", IsHeader = false},
                    new ComboBoxItem {DisplayText = "Header2", IsHeader = true},
                    new ComboBoxItem {DisplayText = "Item4", IsHeader = false},
                    new ComboBoxItem {DisplayText = "Item5", IsHeader = false},
                    new ComboBoxItem {DisplayText = "Item6", IsHeader = false},
                };

            DataContext = list;
        }
    }

    public class ComboBoxItem
    {
        public string DisplayText { get; set; }
        public bool IsHeader { get; set; }
    }
}

试试看这里:我试过这个代码,没有按我的要求返回。。在不同的地方工作ways@sparky68967那个解决方案真是糟糕透顶。@HighCore我并没有以这种或那种方式担保这个解决方案。我只不过是提供了一个选择。说WinForms不支持定制就像说汽车也不能定制一样。当然,您可以立即从经销商处购买升级版,但没有什么可以阻止您通过一点努力添加自己的自定义项。@sparky68687通过一点努力,很抱歉,但我的意见是框架支持特定的东西,如果使用该框架可以实现这一点,而不必花一整天的时间进行黑客攻击来实现您想要的。我希望您发布基于winforms的解决方案,以解决组合框中项目之间的不同外观,例如标题为粗体的项目,以及带有页边空白的项目,如OP要求的项目。+1 HighCore回答不错,但您假设OP知道XAML和WPF@hanspassant我的整合论点仍然成立,我的解决方案可以放在winforms中的ElementHost中。这对于winforms的解决方案很有用:@vincenzolopalo如果winforms真的支持WPF支持的所有东西,那将非常有用。不幸的是,事实并非如此,这就是为什么你应该立即考虑将其彻底销毁,并使用更新、更具可扩展性、更高性能、更高效的框架。@Vincenzolpalo不过,如果你想在使用winforms时伤害自己,你可以尝试一下,它可以用来在winforms应用程序中承载WPF内容,然后你可以把我例子中的组合框放在ElementHost中。你的解决方案是一个黑客。并且没有为OP要求的标题提供视觉上的差异。他不太清楚,除了空格之外,他想要任何视觉上的差异。谢谢你的友好。然而,你的回答完全回避了这个问题,你在一个完全不同的框架中提供了一个解决方案!为什么不使用Qt给出答案?因为Qt实际上并没有取代winforms。WPF有。你的回答非常固执己见。当然,我同意使用WPF可能更好,但这并没有回答问题。我的Qt评论很讽刺,因为回答问题本身是一种明确的实践,而不是使用程序员可能一无所知的不同框架。页边空白和文本中的空格在一起。虽然我承认他在示例中暗示了这一点,但他不清楚是否希望将类别格式化为粗体。如果他需要格式化,我当然建议他使用WPF或一些第三方控件库,而不是自定义绘制控件。但是,这仍然不能回答他的问题,这个问题被清楚地标记为winforms。
using System.Collections.Generic;
using System.Windows;

namespace WpfApplication5
{
    public partial class Window2 : Window
    {
        public Window2()
        {
            InitializeComponent();

            var list = new List<ComboBoxItem>
                {
                    new ComboBoxItem {DisplayText = "Header1", IsHeader = true},
                    new ComboBoxItem {DisplayText = "Item1", IsHeader = false},
                    new ComboBoxItem {DisplayText = "Item2", IsHeader = false},
                    new ComboBoxItem {DisplayText = "Item3", IsHeader = false},
                    new ComboBoxItem {DisplayText = "Header2", IsHeader = true},
                    new ComboBoxItem {DisplayText = "Item4", IsHeader = false},
                    new ComboBoxItem {DisplayText = "Item5", IsHeader = false},
                    new ComboBoxItem {DisplayText = "Item6", IsHeader = false},
                };

            DataContext = list;
        }
    }

    public class ComboBoxItem
    {
        public string DisplayText { get; set; }
        public bool IsHeader { get; set; }
    }
}