Balttazarr
Balttazarr

Reputation: 75

Displaying a Tooltip for ComboBoxItem - works after moving the mouse, but not on first try

I'm using WPF ComboBox with only two items in the Combobox. I display the Tooltip for each ComboboxItem by comparing the item.Content to a property that one class includes like this :

private void OnMouseHover(object sender, MouseEventArgs e)
{
    var lineSelected = (modelGPZ.GetLineWyList().FirstOrDefault(x => x.isSelected == true));
    ComboBoxItem item = sender as ComboBoxItem;
    if ((double)item.Content == lineSelected.LiniaWyComboBox[0])
    {
        item.ToolTip = "This is the first Item";
    }
    if((double)item.Content == lineSelected.LiniaWyComboBox[1])
    {
        item.ToolTip = "This is the second Item";
    }
}

The problem is that when I open the Combobox for the first time I don't get the Tooltip... Strange because the method is called when I debug it. What is more weird, when I hover my mouse over one item, and then another and at last to the first one.. my tooltip shows up..

I tried changing the event to MouseEnter which does not even call the method and what I thought so other related events for this such kind of action. MSDN ComboBox Class

XAML for calling the mentiod method:

<ComboBox.ItemContainerStyle >
    <Style TargetType="{x:Type ComboBoxItem}">
        <EventSetter Event="MouseMove"  Handler="OnMouseHover"/>
    </Style>
</ComboBox.ItemContainerStyle>

For MouseMove and MouseLeave work as mentioned. For GotFocus the problem is isEditable=True - focus stayes on the TextBlock unfortunatelly.

ComboBox in MainWindows.xaml:

<DataGridTemplateColumn Header="PRĄD POJEMNOŚCIOWY [A]" HeaderStyle="{StaticResource PRAD_POJEMNOSCIOWY}">
 <DataGridTemplateColumn.CellTemplate>
   <DataTemplate>
    <ComboBox x:Name="PradPojemnosciowyComboBox"
              ItemsSource="{Binding LiniaWyComboBox, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
              SelectedItem="{Binding SelectedItemComboBox, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
              IsEditable="True"
              IsReadOnly="False"
              Text="{Binding Prad_pojemnosciowy, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
              IsTextSearchEnabled="False"
              IsSynchronizedWithCurrentItem="True"
              PreviewKeyDown="PradPojemnosciowyComboBox_OnPreviewKeyDown">
    <ComboBox.Style>
    <Style TargetType="{x:Type ComboBox}">
      <Style.Triggers>
        <Trigger Property="SelectedValue" Value="{x:Null}">
         <Setter Property="SelectedItem" Value="{Binding SelectedItemComboBox, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
        </Trigger>
      </Style.Triggers>
     </Style>
    </ComboBox.Style>

     <ComboBox.ItemContainerStyle >
      <Style TargetType="{x:Type ComboBoxItem}">
       <EventSetter Event="GotFocus"  Handler="PradPojemnosciowyComboBox_GotFocus"/>
      </Style>
     </ComboBox.ItemContainerStyle>
   </ComboBox>
  </DataTemplate>
 </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

Upvotes: 2

Views: 528

Answers (2)

Rekshino
Rekshino

Reputation: 7325

The behavior is logically imho. First you have no ToolTip for ComboBoxItem, on first time MouseMove ToolTip being set, but it's already too late to trigger it ToolTip(it seems ToolTip triggered earlier than MouseMove for ComboBoxItem being fired). So you can see the ToolTip only second time you enter the item.

Attach all to the GotFocus and it will work as expected:

<ComboBox.ItemContainerStyle >
    <Style TargetType="{x:Type ComboBoxItem}">
        <EventSetter Event="GotFocus"  Handler="ComboBoxItem_GotFocus"/>
    </Style>
</ComboBox.ItemContainerStyle>

private void ComboBoxItem_GotFocus(object sender, RoutedEventArgs e)
{
    var lineSelected = (modelGPZ.GetLineWyList().FirstOrDefault(x => x.isSelected == true));
    ComboBoxItem item = sender as ComboBoxItem;
    if ((double)item.Content == lineSelected.LiniaWyComboBox[0])
    {
        item.ToolTip = "This is the first Item";
    }
    if ((double)item.Content == lineSelected.LiniaWyComboBox[1])
    {
        item.ToolTip = "This is the second Item";
    }
}

Better way is to create in ViewModel a property ItemToolTip in the object, which is DataContext for the ComboBoxItem and bind it:

<ComboBox.ItemContainerStyle >
    <Style TargetType="{x:Type ComboBoxItem}">
        <Setter Property="ToolTip">
            <Setter.Value>
                <ToolTip Content="{Binding ItemToolTip}"/>
            </Setter.Value>
        </Setter>
    </Style>
</ComboBox.ItemContainerStyle>

Example how to prepare data in ViewModel:

public List<object> CbxItemsSource { get; set; } = InitCbxSource();
private static List<object> InitCbxSource()
{
    var dblLst = new List<double>() { 1, 2, 3 };
    return dblLst.Select(dbl => (object)new { ItemValue = dbl, ItemToolTip = "e.g. item index " + dblLst.IndexOf(dbl)}).ToList();
}

Upvotes: 1

Konrad Śledziewski
Konrad Śledziewski

Reputation: 120

I think it's better option to use ToolTipOpening from ComboBox class than OnMouseHover. Checkout my solution:

        <ComboBox>
            <ComboBoxItem ToolTip="" ToolTipOpening="ComboBox_OnToolTipOpening">13.42</ComboBoxItem>
            <ComboBoxItem ToolTip="" ToolTipOpening="ComboBox_OnToolTipOpening">15.82</ComboBoxItem>
        </ComboBox>

And now code-behind for ToolTip manipulation:

        private void ComboBox_OnToolTipOpening(object sender, ToolTipEventArgs e)
        {
            ComboBoxItem item = sender as ComboBoxItem;

            if (item.Content.Equals("13.42"))
            {
                item.ToolTip = "ToolTipItem1";
            }
            else if (item.Content.Equals("15.82"))
            {
                item.ToolTip = "ToolTipItem2";
            }
        }

Upvotes: 0

Related Questions