我需要创建一个自定义组合框控件,该控件允许标题作为分隔符,不应使用鼠标移动或按键选择。
这是示例:
Header1
item1
item2
item3
Header2
item4
item5
我尝试了许多解决方案,但没有成功。提前致谢!
再一次,WPF 可以轻松地提供解决方案,这些解决方案需要在 winforms 中进行大量可怕的 hack。
将我的代码复制并粘贴到 Visual Studio 中的 File -> New Project -> WPF Application 中。
您会很快注意到,我的解决方案不仅为 Header Items 提供了不同的视觉外观,而且还防止了不必要的选择,无论是通过鼠标还是键盘,并且它不需要子类化常规 ComboBox 类,这会导致更少可维护性。
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>
代码背后:
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; }
}
}
试试这个自定义组合框。它忽略标题,但标题的绘制与任何其他项目完全相同,当您选择子项目时,它将包含那些额外的空格。但希望这会引导您朝着正确的方向前进。
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);
}
}