3

I'm relatively new to WPF, so bear with me.

I'm trying to set the background colour of a combo box when it receives focus. I'm setting a trigger in the control template for it's togglebutton to change colour on mouse over, and when it receives focus. Mouse over works fine, but when I tab into the combobox nothing happens until I tab a second time(It changes colour then).

So what I want is for the background colour to change when the user first tabs in.

Any help would be greatly appreciated.

<SolidColorBrush x:Key="ComboBoxNormalBorderBrush" Color="Black" />
<SolidColorBrush x:Key="ComboBoxNormalBackgroundBrush" Color="#fff" />
<SolidColorBrush x:Key="ComboBoxDisabledForegroundBrush" Color="#888" />
<SolidColorBrush x:Key="ComboBoxDisabledBackgroundBrush" Color="#eee" />
<SolidColorBrush x:Key="ComboBoxDisabledBorderBrush" Color="#888" />



<ControlTemplate TargetType="ToggleButton" x:Key="ComboBoxToggleButtonTemplate">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition Width="20" />
        </Grid.ColumnDefinitions>
        <Border 
            Grid.ColumnSpan="2"
            Name="Border"
            BorderBrush="{StaticResource ComboBoxNormalBorderBrush}" 
            CornerRadius="0" BorderThickness="0.6" 
            Background="{StaticResource YellowBrush}">

        </Border>
        <Border 
            Grid.Column="1" 
            Margin="1" 
            BorderBrush="#444" 
            Name="ButtonBorder"
            CornerRadius="0, 0, 0, 0" 
            BorderThickness="2" 
            Background="Gray" />

        <Path Name="Arrow" Grid.Column="1" 
        Data="M0,0 L0,2 L4,6 L8,2 L8,0 L4,4 z"
        HorizontalAlignment="Center" Fill="White"
        VerticalAlignment="Center" />
    </Grid>
    <ControlTemplate.Triggers>
        <Trigger Property="ToggleButton.IsMouseOver" Value="true">
            <Setter TargetName="Border" Property="Background" Value="{StaticResource YellowBrush1}" />
        </Trigger>
        <Trigger Property="ToggleButton.IsFocused" Value="True">
            <Setter TargetName="Border" Property="Background" Value="{StaticResource YellowBrush1}" />
        </Trigger>

        <Trigger Property="UIElement.IsMouseOver" Value="True">
            <Setter Property="Panel.Background" TargetName="ButtonBorder" Value="DarkGray"/>
        </Trigger>
        <Trigger Property="ToggleButton.IsChecked" Value="True">
            <Setter Property="Panel.Background" TargetName="ButtonBorder" Value="LightGray"/>

            <Setter Property="Shape.Fill" TargetName="Arrow" Value="Black"/>
        </Trigger>
        <Trigger Property="UIElement.IsEnabled" Value="False">
            <Setter Property="Panel.Background" TargetName="Border" Value="{StaticResource ComboBoxDisabledBackgroundBrush}"/>
            <Setter Property="Panel.Background" TargetName="ButtonBorder" Value="{StaticResource ComboBoxDisabledBackgroundBrush}"/>
            <Setter Property="Border.BorderBrush" TargetName="ButtonBorder" Value="{StaticResource ComboBoxDisabledBorderBrush}"/>
            <Setter Property="TextElement.Foreground" Value="{StaticResource ComboBoxDisabledForegroundBrush}"/>
            <Setter Property="Shape.Fill" TargetName="Arrow" Value="#999"/>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

<Style TargetType="{x:Type ComboBox}">
    <Setter Property="UIElement.SnapsToDevicePixels" Value="True"/>
    <Setter Property="FrameworkElement.OverridesDefaultStyle" Value="True"/>
    <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
    <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
    <Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
    <Setter Property="TextElement.Foreground" Value="Black"/>
    <Setter Property="Height" Value="25"/>
    <Setter Property="Margin" Value="0,0,0,4"/>
    <Setter Property="BorderThickness" Value="2"/>
    <Setter Property="IsEditable" Value="False"/>
    <Setter Property="BorderBrush" Value="Black"/>
    <Setter Property="FrameworkElement.FocusVisualStyle" Value="{x:Null}"/>
    <Setter Property="Background" Value="{StaticResource NouvemYellowBrush}"/>
    <Setter Property="Control.Template">
        <Setter.Value>
            <ControlTemplate TargetType="ComboBox">
                <Grid>
                    <ToggleButton Name="ToggleButton"
                                  ClickMode="Press" 
                                  Focusable="True"
                                  IsChecked="{Binding Path=IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
                                  Template="{StaticResource ComboBoxToggleButtonTemplate}"/>

                    <ContentPresenter Name="ContentSite" Margin="5, 3, 23, 3" IsHitTestVisible="False"
                          HorizontalAlignment="Left" VerticalAlignment="Center"  
                 Focusable="False"
                          Content="{TemplateBinding ComboBox.SelectionBoxItem}" 
                          ContentTemplate="{TemplateBinding ComboBox.SelectionBoxItemTemplate}"
                          ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"/>

                    <TextBox Name="PART_EditableTextBox" Margin="3, 3, 23, 3"                     
                             IsReadOnly="{TemplateBinding IsReadOnly}"
                             Visibility="Hidden" Background="Transparent"
                             HorizontalAlignment="Left" VerticalAlignment="Center"
                             Focusable="False">
                        <TextBox.Template>
                            <ControlTemplate TargetType="TextBox">
                                <Border Name="PART_ContentHost" Focusable="False"/>
                            </ControlTemplate>
                        </TextBox.Template>
                    </TextBox>

                    <!-- Popup showing items -->
                    <Popup Name="Popup"
                           Placement="Bottom"
                           Focusable="False" 
                           AllowsTransparency="True"
                           IsOpen="{TemplateBinding ComboBox.IsDropDownOpen}"
                           PopupAnimation="Slide">

                        <Grid Name="DropDown" SnapsToDevicePixels="True"
                              MinWidth="{TemplateBinding FrameworkElement.ActualWidth}"
                              Focusable="False"
                              MaxHeight="{TemplateBinding ComboBox.MaxDropDownHeight}">
                            <Border Name="DropDownBorder" 
                                Background="White" 
                                    Focusable="False"
                                Margin="0, 1, 0, 0"
                                CornerRadius="0" 
                                BorderThickness="1" 
                                BorderBrush="Black"/>
                            <ScrollViewer Margin="4" SnapsToDevicePixels="True" Focusable="False">
                                <ItemsPresenter KeyboardNavigation.DirectionalNavigation="Contained" Focusable="False"/>
                            </ScrollViewer>
                        </Grid>
                    </Popup>
                </Grid>
                <ControlTemplate.Triggers>

                    <Trigger Property="ItemsControl.HasItems" Value="False">
                        <Setter Property="FrameworkElement.MinHeight" TargetName="DropDownBorder" Value="95"/>
                    </Trigger>
                    <Trigger Property="UIElement.IsEnabled" Value="False">
                        <Setter Property="TextElement.Foreground" Value="{StaticResource ComboBoxDisabledForegroundBrush}"/>
                    </Trigger>
                    <Trigger Property="ItemsControl.IsGrouping" Value="True">
                        <Setter Property="ScrollViewer.CanContentScroll" Value="False"/>
                    </Trigger>
                    <Trigger Property="ComboBox.IsEditable" Value="True">
                        <Setter Property="KeyboardNavigation.IsTabStop" Value="False"/>
                        <Setter Property="UIElement.Visibility" TargetName="PART_EditableTextBox" Value="Visible"/>
                        <Setter Property="UIElement.Visibility" TargetName="ContentSite" Value="Hidden"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>


</Style>

Edit: showing the relevant view

<i:Interaction.Triggers>
    <i:EventTrigger EventName="Loaded">
        <command:EventToCommand Command="{Binding OnLoadingCommand}" PassEventArgsToCommand="True"/>
    </i:EventTrigger>
    <i:EventTrigger EventName="Unloaded">
        <command:EventToCommand Command="{Binding OnClosingCommand}" PassEventArgsToCommand="True"/>
    </i:EventTrigger>
</i:Interaction.Triggers>

<Grid>

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="3*"/>
        <ColumnDefinition Width="11*"/>
        <ColumnDefinition Width="14*"/>
        <ColumnDefinition Width="14*"/>
        <ColumnDefinition Width="14*"/>
        <ColumnDefinition Width="14*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height=".2*"/>
        <RowDefinition Height="3.5*"/>
        <RowDefinition Height="8*"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <Grid x:Name="GridGlobalData" Grid.Row="1" Grid.ColumnSpan="6">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>

        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!--left side-->
        <Label Content="Code _________________________________________________________________________________________________________________"/>
        <Label Content="Name _________________________________________________________________________________________________________________" Grid.Row="1"/>
        <Label Content="Business Partner Type ________________________________________________________________________" Grid.Row="2"/>
        <Label Content="Group _________________________________________________________________________________________________________________" Grid.Row="3"/>
        <Label Content="Currency ___________________________________________________________________________________________________________" Grid.Row="4"/>


        <TextBox x:Name="TextBoxCode" Text="{Binding PartnerCode, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1">
            <TextBox.InputBindings>
                <KeyBinding Command="{Binding ControlButtonCommand}" CommandParameter="Add" Key="A"  Modifiers="Control" />
                <KeyBinding Command="{Binding FindBusinessPartnerCommand}" CommandParameter="Code"  Key="Enter"/>
            </TextBox.InputBindings>
        </TextBox>

        <TextBox Text="{Binding PartnerName, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Grid.Row="1">
            <TextBox.InputBindings>
                <KeyBinding Command="{Binding FindBusinessPartnerCommand}" CommandParameter="Name"  Key="Enter"/>
            </TextBox.InputBindings>
        </TextBox>
        <ComboBox ItemsSource="{Binding BusinessPartnerTypes}" DisplayMemberPath="Type" SelectedItem="{Binding PartnerType}" SelectedIndex="0" Grid.Column="1" Grid.Row="2"/>
        <ComboBox ItemsSource="{Binding BusinessPartnerGroups}" DisplayMemberPath="BPGroupName" SelectedItem="{Binding PartnerGroup}" SelectedIndex="0" Grid.Column="1" Grid.Row="3"/>
        <ComboBox ItemsSource="{Binding BusinessPartnerCurrencies}" DisplayMemberPath="Name" SelectedItem="{Binding PartnerCurrency}" SelectedIndex="0" Grid.Column="1" Grid.Row="4"/>


        <!--right side-->
        <Label Content="Display Currency _________________________________________________________________________________________________________________" Grid.Column="3" />
        <Label Content="Invoices _________________________________________________________________________________________________________________" Grid.Column="3" Grid.Row="1"/>
        <Label Content="Deliveries _________________________________________________________________________________________________________________" Grid.Column="3" Grid.Row="2"/>
        <Label Content="Orders _________________________________________________________________________________________________________________" Grid.Column="3" Grid.Row="3"/>
        <ComboBox ItemsSource="{Binding BusinessPartnerCurrencies}" DisplayMemberPath="Name" SelectedItem="{Binding DisplayCurrency}" Style="{StaticResource StyleComboBoxReadonly}" SelectedIndex="0" Grid.Column="4"/>
        <TextBox Style="{StaticResource StyleTextBoxNonEditable}" Grid.Column="4" Grid.Row="1"/>
        <TextBox Style="{StaticResource StyleTextBoxNonEditable}" Grid.Column="4" Grid.Row="2"/>
        <TextBox Style="{StaticResource StyleTextBoxNonEditable}" Grid.Column="4" Grid.Row="3"/>

    </Grid>

    <TabControl SelectedIndex="{Binding SelectedPartnerView}" Grid.Row="2" Grid.ColumnSpan="6" >
        <TabItem Header="General">
            <BusinessPartner:BPGeneralView />    
        </TabItem>

        <TabItem Header="Contacts">
            <BusinessPartner:BPContactView />
        </TabItem>

        <TabItem Header="Addresses">
            <BusinessPartner:BPAddressesView />
        </TabItem>

        <TabItem Header="Payment Terms"> 
            <BusinessPartner:BPPaymentTerms />
        </TabItem>

        <TabItem Header="Properties">
            <BusinessPartner:BPPropertiesView />
        </TabItem>

        <TabItem Header="Remarks">
            <BusinessPartner:BPRemarksView />
        </TabItem>

        <TabItem Header="Attachments">
            <BusinessPartner:BPAttachmentsView />
        </TabItem>

    </TabControl>

    <Grid x:Name="GridCrontrolButtons" Grid.Row="3" Grid.ColumnSpan="6">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="7*"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <data:CrudView Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"/>
    </Grid>
</Grid>

mockingbird
  • 31
  • 1
  • 4

2 Answers2

1

You should be able to achieve this by adding an additional IsKeyboardFocused trigger alongside your MouseOver and IsFocused triggers in the ToggleButton control template:

<Trigger Property="IsKeyboardFocused" Value="True">
    <Setter TargetName="Border" Property="Background" Value="{StaticResource YellowBrush1}" />
</Trigger>

MSDN: https://msdn.microsoft.com/en-us/library/bb613567%28v=vs.110%29.aspx (Scroll down to IsKeyboardFocused section)

UPDATE:

The problem in this case is to do with where you're setting your triggers. You're relying on the ToggleButton to have focus so that you can change it's background colour - but in actual fact you want to the content of the combobox to have focus.

The reason you have to TAB twice to apparently achieve focus is because for each ComboBox you're tabbing between the control's ToggleButton, and then the ComboBox selected item (through the ContentPresenter).

One possible fix: First you need to prevent your ToggleButton in your ComboBox template from getting focus:

<ToggleButton Name="ToggleButton"
    ClickMode="Press" 
    Focusable="False"
    IsTabStop="False" ... >

I've actually removed ALL of the Focusable="False" setters from your ToggleButton template as they're not needed.

Then make your ToggleButton template transparent (Border.Background), and remove the existing triggers that affect the Border.Background colour.

Now move to your ComboBox template and give the root <Grid> a name. I've called it templateRoot in my example.

<Setter.Value>
    <ControlTemplate TargetType="ComboBox">
        <Grid Name="templateRoot">
            <ToggleButton Name="ToggleButton" ... >

And now set the background colour for your combobox using that templateRoot. You can add the Triggers you removed from the ToggleButton template to the ComboBox template:

<Trigger Property="IsKeyboardFocused" Value="True">
    <Setter Property="Background" TargetName="templateRoot" Value="{StaticResource YellowBrush1}" />
</Trigger>
... and the other triggers.

With this approach, you're relying on the ComboBox control to trigger your changes when it has focus.

If this solution doesn't work for your needs, then I hope at least you can see where the problem you're having originates.

olitee
  • 1,683
  • 10
  • 12
0

You shouldn't need to go to the level of editing the template for this, just the style:

<ComboBox>
    <ComboBoxItem>Apple</ComboBoxItem>
    <ComboBoxItem>Banana</ComboBoxItem>
    <ComboBoxItem>Pear</ComboBoxItem>
    <ComboBox.Style>
        <Style TargetType="{x:Type ComboBox}">
            <Style.Triggers>
                <Trigger Property="IsFocused" Value="True">
                    <Setter Property="Background" Value="Violet" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </ComboBox.Style>
</ComboBox> 
James Willock
  • 1,999
  • 14
  • 17