0
votes

I'm trying to remove the hover state that a user might have on a ComboBoxItem when this user is using the keyboard arrows to navigate through the items. But, when the user moves his mouse over an item, the hover state / selection state goes to this item.

Right now, with a stock WPF ComboBox, I found out that there is three states with different combinaisons: focused, hover, selected. For example, in the following screenshot, the item3 is the one that was selected, item5 has the mouse hover state and the item7 is the one with the keyboard focus.

enter image description here

I want the behaviour of my ComboBox to be like this

<!DOCTYPE html>
 <html>
    <body>
      <select>
        <option value="Item1">Item #1</option>
        <option value="Item2">Item #2</option>
        <option value="Item3">Item #3</option>
        <option value="Item4">Item #4</option>
     </select>
   </body>
 </html>
  • When I enter the drowndown, the "selected" (blue in this case) value is already selected.
  • If I mouse over an item, this item becomes the one that is "selected".
  • From there, if I use the arrows on my keyboard, the "selected" item is changed and there is no items in the hovered state until I move my mouse again.

I tried using VisualStates and Trigger on the Selected and MouseOver states, but it didn't seemed to be working. I also checked and it could be done with EventSetters but I don't know on which Event to attach the handler to detect the mouse mouvement on top of a ComboBoxItem.

Thank you in advance for you help!

2
In your HTML example, hovering doesn't actually select the element, because the value inside the combo box itself is not updated.rucamzu
You're right. The value is not selected but it is shown as the one that will by selected if I click on it or pressed enter. This would be the behaviour I would like.EverydayLearner

2 Answers

0
votes

I am not sure that this is your goal, but give it a try to see if it is what you want:

<ComboBox Height="50" Width="100" HorizontalAlignment="Left" VerticalAlignment="Top"
              IsEditable="False">
        <ComboBox.Resources>
            <Style TargetType="ComboBoxItem">
                <Setter Property="IsSelected" Value="{Binding RelativeSource={RelativeSource Self}, Path=IsFocused, Mode=OneWay}"/>
            </Style>
        </ComboBox.Resources>
        <ComboBoxItem Content="Items 1" />
        <ComboBoxItem Content="Items 2" />
        <ComboBoxItem Content="Items 3" />
        <ComboBoxItem Content="Items 4" />
    </ComboBox>

You could have the Combobox bound for ItemsSource, it does not matter when the ComboboxItems come from.

0
votes

I found a way of doing this with a simple EventSetter.

<EventSetter Event="MouseMove" Handler="ComboBoxItemStyle_OnMouseMove" />

This event setter is applied directly to the style of my ComboBoxItem. Here is the code of this event handler:

private void ComboBoxItemStyle_OnMouseMove(object sender, MouseEventArgs e)
{
    var hoveredItem = sender as ComboBoxItem;
    hoveredItem?.Focus();
}

My ComboBoxItem also has the property OverrideDefaultStyle to True and therefore I can set the way the ComboBoxItems are shown when Hovered, Focused and Selected. I decided to go with VisualStates on the Template of an item in order to do this.

When an item is in the Focused state, I set the Background to the color I wanted and same thing with the Foreground. I also did the same with the Selected state. Since, the MouseMove event sets the the current hovered item to the one focused, the states kicked in and the styles were set accordingly.