WPF template overridden when custom style applied - wpf

I have a global style defined for a combobox in app.xaml as below:
<Style x:Key="{x:Type ComboBox}" TargetType="ComboBox">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
<Setter Property="MinHeight" Value="20"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Grid Width="{TemplateBinding Width}">
<ToggleButton
Name="ToggleButton"
Template="{StaticResource ComboBoxToggleButton}"
Grid.Column="2"
Focusable="false"
IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
ClickMode="Press">
</ToggleButton>
<ContentPresenter
Name="ContentSite"
IsHitTestVisible="False"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
Margin="3,3,23,3"
VerticalAlignment="Center"
HorizontalAlignment="Left" />
<TextBox x:Name="PART_EditableTextBox"
Style="{x:Null}"
Template="{StaticResource ComboBoxTextBox}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Margin="3,3,23,3"
Focusable="True"
Background="Transparent"
Visibility="Hidden"
IsReadOnly="{TemplateBinding IsReadOnly}"/>
<Popup
Name="Popup"
Placement="Bottom"
IsOpen="{TemplateBinding IsDropDownOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Slide">
<Grid
Name="DropDown"
SnapsToDevicePixels="True"
MinWidth="{TemplateBinding ActualWidth}"
MaxHeight="{TemplateBinding MaxDropDownHeight}">
<Border x:Name="DropDownBorder" Background="{StaticResource BackgroundBrush}" />
<ScrollViewer Margin="4,4,4,4" SnapsToDevicePixels="True" Style="{StaticResource DropDownScrollViewer}">
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
</ScrollViewer>
</Grid>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasItems" Value="false">
<Setter TargetName="DropDownBorder" Property="MinHeight" Value="95"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
</Trigger>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</Trigger>
<Trigger Property="IsEditable" Value="true">
<Setter Property="IsTabStop" Value="false"/>
<Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible"/>
<Setter TargetName="ContentSite" Property="Visibility" Value="Hidden"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Then I create a combobox in a control:
<ComboBox Name="DataTypeSelector" ItemsSource="{Binding ElementName=DataItemsBuildWindow, Path=DataContext.Types}" SelectedValue="{Binding DataType}" HorizontalAlignment="Stretch" />
The style is applied as expected.
If I change my combobox in the control to the below, the combobox goes back to its original style and the width and triggers defined work. It seems that the new global style is ignored.
<ComboBox Name="DataTypeSelector" ItemsSource="{Binding ElementName=DataItemsBuildWindow, Path=DataContext.Types}" SelectedValue="{Binding DataType}" HorizontalAlignment="Stretch">
<ComboBox.Style>
<Style TargetType="ComboBox">
<Setter Property="Width" Value="160"></Setter>
<Style.Triggers>
<DataTrigger Value="List" Binding="{Binding SelectedValue, ElementName=DataTypeSelector, Converter={StaticResource ToStringConverter}}">
<Setter Property="Width" Value="80" />
</DataTrigger>
</Style.Triggers>
</Style>
</ComboBox.Style>
</ComboBox>
How can I keep the global style but also apply the custom triggers?

You have to base the new style on the existing default style:
<ComboBox.Style>
<Style TargetType="ComboBox"
BasedOn="{StaticResource ResourceKey={x:Type ComboBox}}">
...
</Style>
</ComboBox.Style>
By the way, it is not necessary to set the key of the default style in the resource dictionary in App.xaml. If you specify TargetType="ComboBox" the key is set to that type by default. So this is sufficient:
<Style TargetType="ComboBox">
...
</Style>

Related

Why is wpf combobox not being drawn, even though the visibility is set to "true"?

I have a Combobox whose Visibility is bound to a bool Property in ViewModel. The Combobox is located inside a stackPanel:
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<ComboBox Height="50" Style="{StaticResource GameBalanceComboBox}" MinWidth="130" Margin="5 0" ItemsSource="{Binding SlotsBalances}" DisplayMemberPath="Name" Visibility="{Binding IsBalanceShowVis, Converter={StaticResource booleanToVisibility}}" SelectedItem="{Binding SelectBalance}" Background="#411A10" HorizontalAlignment="Right">
<ComboBox.Effect>
<DropShadowEffect Opacity="0.5" Color="Black" Direction="270" BlurRadius="4" ShadowDepth="1"/>
</ComboBox.Effect>
</ComboBox>
</StackPanel>
The problem is that when the event is raised (user logged in) which sets the Visibility bound value to true, the combobox is not shown, even though it's visibility is set to "Visible", BUT when I open another UserControl and then go back to the one with the Combobox, it gets drawn. The Visibility bound property gets set to true and then a boolToVis converter is used.
What can I do to fix this issue?
Below are the screenshots:
The combobox is inside the red border (visual studio debugger)
Here's a screenshot from Visual Studio's Live Property Explorer
Here's what the Combobox actually looks like
EDIT: The UserLoggedIn event handler code:
public void Handle(UserLoggedIn mess)
{
SlotsBalances.Clear();
SlotsBalances.AddRange(User.Instance.Balances.Where(el => (el.Type == 0) || (el.Type == 2)));
SelectBalance = SlotsBalances.FirstOrDefault(el => (el.Type == 0));
NotifyOfPropertyChange("IsBalanceShowVis");
}
The IsBalanceShowVis property:
public bool IsBalanceShowVis { get { return SlotsBalances.Count > 1; } }
private bool _isBalanceShowVis;
As I mentioned earlier, this property is set to true in the event handler
The GameBalanceComboBox style:
<Style TargetType="{x:Type ComboBox}" x:Key="GameBalanceComboBox">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
<Setter Property="FontSize" Value="18"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Grid Background="{TemplateBinding Background}">
<ToggleButton
x:Name="ToggleButton"
Template="{StaticResource GameBalanceToggleButtonComboBox}"
Focusable="false"
IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
ClickMode="Press"
/>
<ContentPresenter
x:Name="ContentSite"
IsHitTestVisible="False"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
Margin="5,0,24,0"
VerticalAlignment="Center"
HorizontalAlignment="Left" />
<TextBox x:Name="PART_EditableTextBox"
Style="{x:Null}"
Template="{StaticResource ComboBoxTextBox}"
HorizontalAlignment="Left"
VerticalAlignment="Stretch"
Margin="5,0,24,0"
Focusable="True"
Background="Transparent"
Visibility="Hidden"
IsReadOnly="{TemplateBinding IsReadOnly}"/>
<Popup
x:Name="Popup"
Placement="Bottom"
IsOpen="{TemplateBinding IsDropDownOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Slide">
<Grid
x:Name="DropDown"
SnapsToDevicePixels="True"
MinWidth="{TemplateBinding ActualWidth}"
MaxHeight="{TemplateBinding MaxDropDownHeight}">
<Border
x:Name="DropDownBorder"
Background="White"
BorderThickness="0" CornerRadius="0 0 3 3"
BorderBrush="{StaticResource CouponToggleButtonBorderBrush}"/>
<ScrollViewer Margin="0 0 0 3" SnapsToDevicePixels="True" PanningMode="VerticalOnly">
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" >
<StackPanel.Resources>
<Style TargetType="{x:Type ComboBoxItem}" BasedOn="{StaticResource GameBalanceComboBoxItem}">
<!--<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
--><!--"#1F72AF"--><!--
<Setter Property="Cursor" Value="Hand"/>
</Trigger>
</Style.Triggers>-->
</Style>
</StackPanel.Resources>
</StackPanel>
</ScrollViewer>
</Grid>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.3"/>
</Trigger>
<Trigger Property="HasItems" Value="false">
<Setter TargetName="DropDownBorder" Property="MinHeight" Value="95"/>
</Trigger>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</Trigger>
<Trigger SourceName="Popup" Property="AllowsTransparency" Value="true">
<Setter TargetName="DropDownBorder" Property="CornerRadius" Value="0 0 4 4"/>
<Setter TargetName="DropDownBorder" Property="Margin" Value="0"/>
</Trigger>
<Trigger Property="IsEditable" Value="true">
<Setter Property="IsTabStop" Value="false"/>
<Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible"/>
<Setter TargetName="ContentSite" Property="Visibility" Value="Hidden"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

How set style combobox programmatically (WPF)

I'have write this code for apply template to ComboBox.
This is code on App.xaml
<Style x:Key="{x:Type ComboBox}" TargetType="ComboBox" x:Name="selectedStyleTrigger">
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
<Setter Property="Width" Value="150"/>
<Setter Property="MinHeight" Value="20"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Grid>
<ToggleButton Name="ToggleButton" Template="{StaticResource ComboBoxToggleButton}" Grid.Column="2"
Focusable="False" IsChecked="{Binding Path=IsDropDownOpen,
Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press" />
<ContentPresenter Name="ContentSite" IsHitTestVisible="False" Content="{TemplateBinding SelectionBoxItem}" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" Margin="3,3,23,3" VerticalAlignment="Center" HorizontalAlignment="Left" />
<TextBox x:Name="PART_EditableTextBox" Style="{x:Null}" Template="{StaticResource ComboBoxTextBox}"
HorizontalAlignment="Left" VerticalAlignment="Center" Margin="3,3,23,3"
Focusable="True" Background="Transparent" Foreground="White"
Visibility="Hidden" IsReadOnly="{TemplateBinding IsReadOnly}"
Width="250"/>
<Popup Name="Popup" Placement="Bottom" IsOpen="{TemplateBinding IsDropDownOpen}"
AllowsTransparency="True" Focusable="False" PopupAnimation="Slide"
Width="200">
<Grid Name="DropDown" SnapsToDevicePixels="True"
MinWidth="{TemplateBinding ActualWidth}" MaxHeight="{TemplateBinding MaxDropDownHeight}">
<Border x:Name="DropDownBorder" Background="#004460" BorderThickness="1" BorderBrush="#004460" />
<ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
</ScrollViewer>
</Grid>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasItems" Value="False">
<Setter TargetName="DropDownBorder" Property="MinHeight" Value="95"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
</Trigger>
<Trigger Property="IsGrouping" Value="True">
<Setter Property="ScrollViewer.CanContentScroll" Value="False"/>
</Trigger>
<Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="True">
<Setter TargetName="DropDownBorder" Property="CornerRadius" Value="0,0,2,2"/>
<Setter TargetName="DropDownBorder" Property="Margin" Value="0,-1,0,0"/>
</Trigger>
<Trigger Property="IsEditable" Value="True">
<Setter Property="IsTabStop" Value="False"/>
<Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible"/>
<Setter TargetName="ContentSite" Property="Visibility" Value="Hidden"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I have this class it extends ComboBox:
public class ComboBoxExtends :ComboBox
{
public LOCAL_PE_AttivitaXParametri parametri { set; get; }
}
Now I insert on Panel the ComboBox in this way:
ComboBoxExtends comboBox = new ComboBoxExtends();
comboBox.Style = Resources["selectedStyleTrigger"] as Style;
grid.Children.Add(comboBox);
I set style "comboBox.Style = Resources["selectedStyleTrigger"] as Style;" but I don't see the style.
How can I fixed it?
Reguards
You have created a Style for the ComboBox and are trying to apply it to your custom ComboBoxExtends class which is not a ComboBox. In order to declare a Style for your custom class, you will need to add an XML Namespace Prefix that points to the assembly where it is declared... perhaps something like this:
xmlns:Local="clr-namespace:YourAppName.OptionalFolderName"
Then you can refer to your custom class using this prefix:
<Style TargetType="Local:ComboBoxExtends" x:Key="selectedStyleTrigger">
...
</Style>

WPF especific style on selected item according to the style of the item

I have a custom combobox where I apply a specific style on the first item. I want that when this item is selected, the style of displayed text in the combobox is the same. Currently, all selected items appear in the same style and I do not know how to make the ContentPresenter "get" the specified style in that item. This is the code:
<ComboBox HorizontalAlignment="Center" Margin="0,106,0,0" VerticalAlignment="Top" Width="200">
<ComboBoxItem Style="{StaticResource mySpecialStyle}">Select an option...</ComboBoxItem>
<ComboBoxItem>ComboBox Item #1</ComboBoxItem>
<ComboBoxItem>ComboBox Item #2</ComboBoxItem>
<ComboBoxItem>ComboBox Item #3</ComboBoxItem>
</ComboBox>
In fact, "mySpecialStyle" only changes color and fontstyle. But when the first item is selected, it appears like any other selected item. How can set this on the Contentpresenter?
Here is the complete code of the custom ComBoBox:
<Window.Resources>
<Style x:Key="mySpecialStyle" TargetType="{x:Type ComboBoxItem}">
<Setter Property="TextElement.FontStyle" Value="Italic"/>
</Style>
<ControlTemplate x:Key="ComboBoxToggleButton" TargetType="{x:Type ToggleButton}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<Border
x:Name="Border"
Grid.ColumnSpan="3"
CornerRadius="3"
Background="#FFFAFAFA"
BorderBrush="#FF999999"
BorderThickness="1" />
<Border
x:Name="Background"
Grid.Column="0"
CornerRadius="3,0,0,3"
Margin="1"
Background="#FFFAFAFA"
BorderBrush="#FF999999"
BorderThickness="0" />
<Path
x:Name="ArrowDw"
Grid.Column="1"
Fill="#FF404040"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M 0 0 L 4 4 L 8 0 Z"/>
<Path
x:Name="ArrowUp"
Grid.Column="1"
Fill="Transparent"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M 0 2 L 4 -2 L 8 2 Z"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="ToggleButton.IsMouseOver" Value="true">
<Setter TargetName="ArrowDw" Property="Fill" Value="#FF000000" />
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="true">
<Setter TargetName="Background" Property="Background" Value="#FFFFFFFF" />
<Setter TargetName="Border" Property="BorderBrush" Value="#FF000000" />
<Setter TargetName="Border" Property="Background" Value="#FFFFFFFF" />
<Setter TargetName="ArrowDw" Property="Fill" Value="Transparent" />
<Setter TargetName="ArrowUp" Property="Fill" Value="#FF404040" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="ToggleButton.IsChecked" Value="True" />
<Condition Property="ToggleButton.IsMouseOver" Value="True" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter TargetName="ArrowUp" Property="Fill" Value="#FF000000" />
</MultiTrigger.Setters>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border" Property="Background" Value="#FFFFFF" />
<Setter TargetName="Border" Property="BorderBrush" Value="#CCCCCC" />
<Setter Property="Foreground" Value="#888888"/>
<Setter TargetName="ArrowDw" Property="Fill" Value="#999999" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate x:Key="ComboBoxTextBox" TargetType="{x:Type TextBox}">
<Border x:Name="PART_ContentHost" Focusable="False" Background="{TemplateBinding Background}"/>
</ControlTemplate>
<Style x:Key="{x:Type ComboBox}" TargetType="{x:Type ComboBox}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
<Setter Property="MinHeight" Value="27"/>
<Setter Property="ToolTip" Value="{Binding Path=SelectionBoxItem, RelativeSource={RelativeSource Self}}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Grid>
<ToggleButton
Name="ToggleButton"
Template="{StaticResource ComboBoxToggleButton}"
Grid.Column="2"
Focusable="false"
IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
ClickMode="Press">
</ToggleButton>
<ContentPresenter
Name="ContentSite"
IsHitTestVisible="False"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
????
Margin="8,3,28,3"
VerticalAlignment="Center"
HorizontalAlignment="Left" />
<TextBox x:Name="PART_EditableTextBox"
Style="{x:Null}"
Template="{StaticResource ComboBoxTextBox}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Margin="8,3,28,3"
Focusable="True"
Background="Transparent"
Visibility="Hidden"
IsReadOnly="{TemplateBinding IsReadOnly}"/>
<Popup
Name="Popup"
Placement="Bottom"
IsOpen="{TemplateBinding IsDropDownOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Slide">
<Grid
Name="DropDown"
SnapsToDevicePixels="True"
MinWidth="{TemplateBinding ActualWidth}"
MaxHeight="{TemplateBinding MaxDropDownHeight}">
<Border
x:Name="DropDownBorder"
Background="#FFFFFF"
BorderThickness="1"
BorderBrush="#FF999999"/>
<ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained"/>
</ScrollViewer>
</Grid>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasItems" Value="false">
<Setter TargetName="DropDownBorder" Property="MinHeight" Value="27"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#888888"/>
</Trigger>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</Trigger>
<Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="true">
<Setter TargetName="DropDownBorder" Property="CornerRadius" Value="4"/>
<Setter TargetName="DropDownBorder" Property="Margin" Value="0,2,0,0"/>
</Trigger>
<Trigger Property="IsEditable" Value="true">
<Setter Property="IsTabStop" Value="false"/>
<Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible"/>
<Setter TargetName="ContentSite" Property="Visibility" Value="Hidden"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
</Style.Triggers>
</Style>
</Window.Resources>
The placeholder "???" is where I need to set the style according to the style defined in the ComboBoxitem (in this case, "mySpecialStyle").
Thanks in advance!
The logic to solve here of course will base on something like a Trigger. However we can't set Style via Setter. So I thought of this hack (but safe enough). Firstly you need to bind the Style of the ContentPresenter to its Tag property (of course 2 way binding by default). Then you just need to change the Tag to a {StaticResource} with ResourceKey being the same as the resource you defined upwards on the tree. This resource should of course have TargetType of ContentPresenter:
<ContentPresenter
Name="ContentSite"
IsHitTestVisible="False"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
Style="{Binding Tag, RelativeSource={RelativeSource Self}}" />
<!-- the additional Trigger should be added to the ControlTemplate.Triggers -->
<Trigger Property="SelectedIndex" Value="0">
<Setter TargetName="ContentSite"
Property="Tag" Value="{StaticResource mySpecialStyle}"/>
</Trigger>

Custom WPF ComboBox doesn't show grouping

I have created a custom ComboBox in WPF
<!-- Combobox template -->
<ControlTemplate x:Key="CustomComboBoxToggleButton" TargetType="ToggleButton">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<Border x:Name="Border" Grid.ColumnSpan="2" CornerRadius="3" Background="{StaticResource CustomDarkBlue}" BorderBrush="{StaticResource CustomWhite}" BorderThickness="2"/>
<Border x:Name="Border2" Grid.Column="0" CornerRadius="3,0,0,3" Margin="1" Background="{StaticResource CustomBackground}" BorderBrush="{StaticResource CustomWhite}" BorderThickness="1,1,2,1"/>
<Path x:Name="Arrow" Grid.Column="1" Fill="{StaticResource CustomGlyph}" HorizontalAlignment="Center" VerticalAlignment="Center" Data="M 0 0 L 4 4 L 8 0 Z"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="ToggleButton.IsMouseOver" Value="True">
<Setter TargetName="Border" Property="Background" Value="{StaticResource CustomDarkBlue}"/>
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="True">
<Setter TargetName="Border" Property="Background" Value="{StaticResource CustomDarkBlue}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border" Property="BorderBrush" Value="{StaticResource CustomGray}"/>
<Setter TargetName="Border2" Property="BorderBrush" Value="{StaticResource CustomGray}"/>
<Setter Property="Foreground" Value="{StaticResource CustomGray}"/>
<Setter TargetName="Arrow" Property="Fill" Value="{StaticResource CustomGray}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!-- Combobox -->
<Style x:Key="RoundedComboBox" TargetType="{x:Type ComboBox}">
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
<Setter Property="Foreground" Value="{StaticResource CustomWhite}"/>
<Setter Property="Background" Value="{StaticResource CustomBackground}"/>
<Setter Property="Height" Value="21"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Grid>
<ToggleButton Name="ToggleButton" Template="{StaticResource CustomComboBoxToggleButton}" Grid.Column="2" Focusable="False" IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press"/>
<ContentPresenter Name="ContentSite" IsHitTestVisible="False" Content="{TemplateBinding SelectionBoxItem}" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" ContentStringFormat="{TemplateBinding SelectionBoxItemStringFormat}" Margin="3,1,23,1" VerticalAlignment="Center" HorizontalAlignment="Left"/>
<Popup Name="Popup" Placement="Bottom" IsOpen="{TemplateBinding IsDropDownOpen}" AllowsTransparency="True" Focusable="False" PopupAnimation="Slide">
<Grid Name="DropDown" SnapsToDevicePixels="True" MinWidth="{TemplateBinding ActualWidth}" MaxHeight="{TemplateBinding MaxDropDownHeight}">
<Border x:Name="DropDownBorder" Background="{StaticResource CustomBackground}" BorderThickness="2" BorderBrush="{StaticResource CustomWhite}"/>
<ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained"/>
</ScrollViewer>
</Grid>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasItems" Value="False">
<Setter TargetName="DropDownBorder" Property="MinHeight" Value="95"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{StaticResource CustomGray}"/>
</Trigger>
<Trigger Property="IsGrouping" Value="True">
<Setter Property="ScrollViewer.CanContentScroll" Value="False"/>
</Trigger>
<Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="True">
<Setter TargetName="DropDownBorder" Property="CornerRadius" Value="4"/>
<Setter TargetName="DropDownBorder" Property="Margin" Value="0,2,0,0"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This is then applied to a ComboBox
<ComboBox Grid.Column="0" x:Name="cboChild" Margin="140,65,0,0" ItemsSource="{Binding Source={StaticResource GroupedData}}" ItemTemplate="{StaticResource AccountTemplate}" SelectedValue="{Binding Source={StaticResource Item}, Path=child}" SelectedValuePath="ID" Width="150" Style="{StaticResource RoundedComboBox}" HorizontalAlignment="Left" VerticalAlignment="Top">
<ComboBox.GroupStyle>
<GroupStyle HeaderTemplate="{StaticResource GroupHeader}"/>
</ComboBox.GroupStyle>
</ComboBox>
The following is found in Window.Resources
<Window.Resources>
<CollectionViewSource Source="{Binding ChildAccounts}" x:Key="GroupedData">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="group"/>
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
<DataTemplate x:Key="GroupHeader">
<TextBlock Text="{Binding group}" Margin="0" Foreground="{StaticResource CustomWhite}"/>
</DataTemplate>
<DataTemplate x:Key="AccountTemplate">
<TextBlock Text="{Binding comment}" Margin="0" Foreground="{StaticResource CustomWhite}"/>
</DataTemplate>
</Window.Resources>
Basically grouping works as it should when the RoundedComboBox style is NOT applied (ie. to the default ComboBox) but whenever the style is applied the drop-down popup is empty
Help!!
Thanks
Andy
Found the answer..... Use <ItemsPresenter ...> instead of <StackPanel ...>
Thanks sa_ddam213 for your helpful advice above regarding the binding.

How to group items inside custom control combobox?

I've been trying to group the items of my custom control combobox using xaml and I'm a little stuck. I've been reading around and found the following code that produces the results I want, but I'd like to move all the code into the GroupedImageComboBox control.
<StackPanel>
<StackPanel.Resources>
<CollectionViewSource x:Key="groupedData" Source="{Binding Items}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="EntityBaseDependencyType" Converter="{StaticResource enumConverter}"/>
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</StackPanel.Resources>
<WPFControls:GroupedImageComboBox
ItemsSource ="{Binding Source={StaticResource groupedData}}"
SelectedItem="{Binding SelectedItem}"
>
<ItemsControl.GroupStyle>
<x:Static Member="GroupStyle.Default"/>
</ItemsControl.GroupStyle>
</WPFControls:GroupedImageComboBox>
</StackPanel>
I would like to be able to remove the use of the stackpanel and the itemscontrol from this area and put them inside the GroupedImageComboBox. Is there a way to achieve this?
Thanks in advance.
Edit 1.
I've been playing with the template and feel that I should be able to do the collectionview manipulations within the DropDown grid - I'm just not sure how....
<Style TargetType="{x:Type WPFControls:ImageComboBox}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
<Setter Property="MinWidth" Value="120"/>
<Setter Property="MinHeight" Value="20"/>
<Setter Property="ItemContainerStyle" Value="{StaticResource CustomComboBoxItemStyle}"/>
<Setter Property="IsSynchronizedWithCurrentItem" Value="true"/>
<Setter Property="Margin" Value="8"/>
<Setter Property="IsEditable" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Grid>
<ToggleButton Name="ToggleButton"
Template="{StaticResource ComboBoxToggleButton}"
Grid.Column="2"
Focusable="false"
IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
ClickMode="Press">
</ToggleButton>
<ContentPresenter Name="ContentSite"
IsHitTestVisible="False"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{StaticResource DiplayImageWithTextDataTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
Margin="3,3,23,3"
VerticalAlignment="Center"
HorizontalAlignment="Left"
/>
<TextBox x:Name="PART_EditableTextBox"
Style="{x:Null}"
Template="{StaticResource ComboBoxTextBox}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Margin="3,3,23,3"
Focusable="True"
Background="Transparent"
Visibility="Hidden"
IsReadOnly="{TemplateBinding IsReadOnly}"/>
<Popup Name="Popup"
Placement="Bottom"
IsOpen="{TemplateBinding IsDropDownOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Slide"
>
<Grid Name="DropDown"
SnapsToDevicePixels="True"
MinWidth="{TemplateBinding ActualWidth}"
MaxHeight="{TemplateBinding MaxDropDownHeight}"
>
<Border x:Name="DropDownBorder"
Background="{StaticResource WindowBackgroundBrush}"
BorderThickness="1"
BorderBrush="{StaticResource SolidBorderBrush}"/>
<ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
<ItemsPresenter KeyboardNavigation.DirectionalNavigation="Contained"
/>
</ScrollViewer>
</Grid>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasItems" Value="false">
<Setter TargetName="DropDownBorder" Property="MinHeight" Value="95"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
</Trigger>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</Trigger>
<Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="true">
<Setter TargetName="DropDownBorder" Property="CornerRadius" Value="4"/>
<Setter TargetName="DropDownBorder" Property="Margin" Value="0,2,0,0"/>
</Trigger>
<Trigger Property="IsEditable" Value="true">
<Setter Property="IsTabStop" Value="false"/>
<Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible"/>
<Setter TargetName="ContentSite" Property="Visibility" Value="Hidden"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
</Style.Triggers>
</Style>
Actually, it seems that in this example, the stack panel IS NOT something you HAVE TO use.
Just move the CollectionViewSource declaration elsewhere (in your </Window.Resources><Window.Resources> tag for example) and put your combobox anywhere else you want.

Resources