Добавить заголовок к Combobox
Есть комбобокс:
<ComboBox
Name="subsystemCombobox"
Height="30"
IsReadOnly="True"
IsEditable="False"
VerticalAlignment="Bottom"
HorizontalAlignment="Left">
<ComboBox.ItemTemplate>
<DataTemplate>
<CheckBox
IsChecked="{Binding IsChecked}"
Width="120"
Content="{Binding SubSystemName}"
Checked="CheckBox_Checked"
/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Как сделать в нем заголовок?
Ответы (1 шт):
Автор решения: vitidev
→ Ссылка
ComboBox просто выводит текущий пункт как он есть, поэтому свой контрол. Вот вам заготовка.
xaml:
<UserControl
x:Class="WpfAppCombo.MyDropDown"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Name="Root"
d:DesignHeight="30"
d:DesignWidth="100"
mc:Ignorable="d">
<Grid>
<ToggleButton Name="OpenPopup" Content="{Binding Header, ElementName=Root, Mode=OneWay}">
<ToggleButton.Template>
<ControlTemplate TargetType="ToggleButton">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<Border
x:Name="Border"
Grid.ColumnSpan="2"
Background="#FFEFEFEF"
BorderBrush="#C0C0C0"
BorderThickness="1"
SnapsToDevicePixels="True" />
<ContentPresenter
Grid.Column="0"
Margin="3,0,3,0"
VerticalAlignment="Center" />
<Path
x:Name="Arrow"
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M 0 0 L 4 4 L 8 0 Z"
Fill="DimGray" />
</Grid>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
<Popup
Width="{Binding ActualWidth, ElementName=OpenPopup}"
AllowsTransparency="True"
IsOpen="{Binding IsChecked, ElementName=OpenPopup}"
StaysOpen="False">
<Border
Padding="5"
Background="White"
BorderBrush="#C0C0C0"
BorderThickness="1"
SnapsToDevicePixels="True">
<ItemsControl ItemTemplate="{Binding ItemTemplate, ElementName=Root, Mode=OneWay}" ItemsSource="{Binding ItemsSource, ElementName=Root, Mode=OneWay}">
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Height" Value="{Binding RowHeight, ElementName=Root, Mode=OneTime}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</Border>
</Popup>
</Grid>
</UserControl>
code-behind:
public partial class MyDropDown : UserControl
{
public MyDropDown()
{
InitializeComponent();
}
public double RowHeight { get; set; } = 23;
public static readonly DependencyProperty ItemTemplateProperty = DependencyProperty.Register(
"ItemTemplate", typeof(DataTemplate), typeof(MyDropDown), new PropertyMetadata(default(DataTemplate)));
public DataTemplate ItemTemplate
{
get => (DataTemplate)GetValue(ItemTemplateProperty);
set => SetValue(ItemTemplateProperty, value);
}
public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register(
"Header", typeof(string), typeof(MyDropDown), new PropertyMetadata(default(string)));
public string Header
{
get => (string)GetValue(HeaderProperty);
set => SetValue(HeaderProperty, value);
}
public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register(
"ItemsSource", typeof(IEnumerable), typeof(MyDropDown), new PropertyMetadata(default(IEnumerable)));
public IEnumerable ItemsSource
{
get => (IEnumerable)GetValue(ItemsSourceProperty);
set => SetValue(ItemsSourceProperty, value);
}
}
использование:
<c:MyDropDown
Width="150"
Height="30"
RowHeight="30"
Header="{Binding Header, Mode=OneWay}"
ItemsSource="{Binding Items, Mode=OneWay}">
<wpfAppCombo:MyDropDown.ItemTemplate>
<DataTemplate>
<CheckBox
VerticalAlignment="Center"
Click="CheckBox_OnClick"
Content="{Binding SubSystemName, Mode=OneWay}"
IsChecked="{Binding IsChecked, Mode=TwoWay}" />
</DataTemplate>
</wpfAppCombo:MyDropDown.ItemTemplate>
</c:MyDropDown>
Где в CheckBox_OnClick обновлять Header (хотя конечно лучше использовать не события, а команды, но mvvm уже выходит за рамки вопроса)
Замечания
- Контрол сделан на коленке, поэтому в нем нет полной стилизации под настоящий комбокбокс, только минимально переопределен шаблон с вшитыми цветами. Также хидер выводит строку, хотя мог бы что угодно
- При огромном количестве пунктов вместо списка можно использовать UniformGrid - будет многоколоночный список
- Событие Checked у CheckBox срабатывает только в одну сторону, поэтому лучше ловить Click
