I’m trying to get a ComboBox to match a visual design, so its ToggleButton has a blue border when the ComboBox has focus. I can’t figure out how to do this and can’t find an example.
When the ComboBox gets focus, the TextBox inside gets the dashed focus visual. How do I pass the ComboBox focus state down to the ToggleButton, so that it’s blue border style is turned on?
Here is my ComboBox template:
<ControlTemplate x:Key="ComboBoxCT" TargetType="{x:Type ComboBox}">
<Grid x:Name="gLayoutRoot"
Margin="{TemplateBinding Margin}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
VerticalAlignment="{TemplateBinding VerticalAlignment}"
MinWidth="{TemplateBinding MinWidth}"
MinHeight="{TemplateBinding MinHeight}"
MaxWidth="{TemplateBinding MaxWidth}"
MaxHeight="{TemplateBinding MaxHeight}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
<ToggleButton x:Name="ToggleButton"
Grid.Column="2"
Focusable="false"
IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
ClickMode="Press"
Style="{DynamicResource ComboBoxToggleStyle}"
/>
<AccessText x:Name="ContentSite"
Style="{StaticResource ComboBoxAccessTextStyle}"
Text="{TemplateBinding SelectionBoxItem}"
Foreground="{TemplateBinding Foreground}"/>
<TextBox x:Name="PART_EditableTextBox"
Style="{x:Null}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
VerticalAlignment="{TemplateBinding VerticalAlignment}"
Margin="2,3,17,2"
Focusable="True"
Background="{DynamicResource InnerBgLight}"
Visibility="Hidden"
IsReadOnly="{TemplateBinding IsReadOnly}">
<TextBox.Template>
<ControlTemplate TargetType="TextBox">
<Border x:Name="PART_ContentHost" Focusable="False" Background="{TemplateBinding Background}" />
</ControlTemplate>
</TextBox.Template>
</TextBox>
<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="OuterBorder"
Style="{DynamicResource OuterBorderBottomRestStyle}"
Background="{DynamicResource InnerBorder}">
<Border x:Name="InnerBorder"
Style="{DynamicResource InnerBottomBorderStyle}">
<ScrollViewer x:Name="scvCbxItems" SnapsToDevicePixels="True">
<StackPanel x:Name="spCbxItemsPanel" IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
</ScrollViewer>
</Border>
</Border>
</Grid>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasItems" Value="false">
<Setter TargetName="InnerBorder" Property="MinHeight" Value="95"/>
</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>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource FgDisabledBrush}"/>
<Setter Property="OpacityMask" TargetName="OuterBorder" Value="{DynamicResource OuterBgDisabledOpacityMask}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
And here’s my ToggleButton template:
<ControlTemplate x:Key="ComboBoxToggleCT" TargetType="{x:Type ToggleButton}">
<Border x:Name="OuterBorder"
Style="{DynamicResource OuterBorderTopRestStyle}">
<Border x:Name="InnerBorder"
Style="{DynamicResource InnerTopBorderStyle}">
<Path x:Name="Arrow"
HorizontalAlignment="Right" VerticalAlignment="Center"
Margin="5"
Fill="{DynamicResource FgBrush}"
Data="{DynamicResource DownArrowGeometry}"/>
</Border>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Style" TargetName="OuterBorder" Value="{DynamicResource OuterBorderTopSelectStyle}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="OpacityMask" TargetName="OuterBorder" Value="{DynamicResource OuterBgDisabledOpacityMask}"/>
<Setter Property="Fill" TargetName="Arrow" Value="{DynamicResource FgDisabledBrush}"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Style" TargetName="OuterBorder" Value="{DynamicResource OuterBorderTopSelectStyle}"/>
<Setter Property="Style" TargetName="InnerBorder" Value="{DynamicResource InnerBorderTopFocusStyle}"/>
</Trigger>
<!--<Trigger Property="IsKeyboardFocused" Value="True">-->
<Trigger Property="IsKeyboardFocused" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsFocused}">
<Setter Property="Style" TargetName="OuterBorder" Value="{DynamicResource OuterBorderBottomFocusStyle}"/>
<Setter Property="Style" TargetName="InnerBorder" Value="{DynamicResource InnerBorderTopFocusStyle}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
As you can see I try to bind to the ComboBox‘s focus state, but that doesn’t work inside the Trigger.
Any help appreciated. Sorry for the noob question. Thanks!
The easiest way to do this is to have a binding to the Templated Parent’s IsFocused. Note: Mode=OneWay is important since IsFocused is read only. You could do something like this: