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; }
}
}