首页 > 解决方案 > 显示 ComboBoxItem 的工具提示 - 移动鼠标后有效,但第一次尝试时无效

问题描述

我正在使用 WPF 组合框,组合框中只有两个项目。item.Content我通过将 与一个类包含的属性进行比较来显示每个 ComboboxItem 的工具提示,如下所示:

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";
    }
}

问题是,当我第一次打开组合框时,我没有得到工具提示...奇怪,因为在调试它时调用了该方法。更奇怪的是,当我将鼠标悬停在一个项目上,然后是另一个项目,最后到第一个项目时……我的工具提示出现了……

我尝试将事件更改为MouseEnter甚至不调用该方法以及我认为其他相关事件的此类操作。 MSDN 组合框类

用于调用mentiod 方法的XAML:

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

如前所述,为MouseMove和工作。MouseLeave因为GotFocus问题是isEditable=True- 不幸的是,焦点停留在 TextBlock 上。

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>

标签: c#wpfmvvmcombobox

解决方案


这种行为在逻辑上是恕我直言。首先你没有ToolTipfor ComboBoxItem, 第一次MouseMove ToolTip被设置,但已经太迟触发它ToolTip(它似乎比被ToolTip触发更早触发)。因此,您只能在第二次进入该项目时看到。MouseMoveComboBoxItemToolTip

将所有内容附加到GotFocus,它将按预期工作:

<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";
    }
}

更好的方法是在 ViewModelItemToolTip对象中创建一个属性,即 DataContextComboBoxItem并绑定它:

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

示例如何在 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();
}

推荐阅读