Windows Form - How add header not selectable in combobox item in C#?

痴心易碎 提交于 2020-01-23 11:06:32

问题


I need create a custom combobox control that allows header as separator which should not be selectable using the mouse move or key press.

this is example:

Header1
  item1
  item2
  item3
Header2
  item4
  item5

I tried many solutions, without success. Thanks in advance!


回答1:


Once again, WPF can easily provide solutions that would require tons of horrible hacks in winforms.

Copy and paste my code in a File -> New Project -> WPF Application in Visual Studio.

You will quickly notice that my solution not only provides a different visual appearance for Header Items, but it also prevents unwanted selection, be it via mouse or keyboard, and it doesn't need to subclass the regular ComboBox class, which would lead to lesser maintainability.

XAML:

<Window x:Class="WpfApplication5.Window2"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication5"
        Title="Window2" Height="300" Width="300">
    <Grid>
        <ComboBox ItemsSource="{Binding}" DisplayMemberPath="DisplayText"
                  VerticalAlignment="Center" HorizontalAlignment="Center" 
                  Height="25" Width="100">
            <ComboBox.ItemContainerStyle>
                <Style TargetType="ComboBoxItem">
                    <Setter Property="Foreground" Value="Black"/>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding IsHeader}" Value="True">
                            <Setter Property="IsEnabled" Value="False"/>
                            <Setter Property="FontWeight" Value="Bold"/>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding IsHeader}" Value="False">
                            <Setter Property="Margin" Value="10,0,0,0"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ComboBox.ItemContainerStyle>
        </ComboBox>
    </Grid>
</Window>

Code Behind:

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



回答2:


Try this custom combo box. It ignores the header, but the header is drawn exactly like any other item and when you select a subitem, it will contain those extra spaces. But hopefully this leads you in the right direction.

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


来源:https://stackoverflow.com/questions/14866064/windows-form-how-add-header-not-selectable-in-combobox-item-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!