在WPF组合框中覆盖鼠标悬停行为

时间:2010-07-27 23:30:23

标签: wpf .net-3.5 wpf-controls

当下拉列表时,鼠标悬停在下拉列表中的某个项目上,该项目将突出显示,但除非单击该项目,否则文本框中显示的选定值不会更改。我正在寻找一种方法来修改从ComboBox继承的控件中的鼠标悬停行为。我试过重写像OnMouseEnter& OnMouseMove等。

3 个答案:

答案 0 :(得分:2)

您可以通过覆盖OnMouseMove来实现。 MouseEventArgs的OriginalSource属性将直接为您提供鼠标下的元素。您可以使用ContainerFromElement获取包含该元素的ComboBoxItem,然后使用ItemContainerGenerator.ItemFromContainer来获取要选择的项目:

protected override void OnMouseMove(MouseEventArgs e)
{
    base.OnMouseMove(e);
    var container = ContainerFromElement((DependencyObject)e.OriginalSource);
    if (container != null)
    {
        SelectedItem = ItemContainerGenerator.ItemFromContainer(container);
    }
}

答案 1 :(得分:0)

使用TextBlock,带箭头的ToggleButton和ListBox创建自己的控件。选中ToggleButton时显示列表框。当用户将鼠标悬停在listboxitem上时,更改文本框中的文本并更新所选项目的某些属性或触发事件。

答案 2 :(得分:0)

这就是我在我的代码中解决相同问题的方法,希望它对其他人有用,或者只是迈向完整的xaml解决方案。

我遵循了Quartermeister的解决方案。但在我看来,需要子类化ComboBox是一个设计弱点(因为这只是为了处理MouseOver事件)。因为我只需要处理MouseOver事件的不同行为,所以我只实现了处理附加到XAML文件的类中的MouseOver事件的方法。

首先,我使用了EventSetter类,它是Setter类的子类,它特定于Events。所以EventSetter可以用来装饰FrameworkElements,就像我们通常使用Setter一样。

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

这样,当鼠标悬停时,每个ComboBoxItem都会调用_updateModel。

我对_updateModel的实现非常直接,它主要基于Quartermeister的工作:

private void _updateModel(object sender, MouseEventArgs e)
{
    DependencyObject src = e.Source as DependencyObject;
    ComboBoxItem cbi = VisualTreeHelper.GetParent(src) as ComboBoxItem;
    while ((cbi == null) && (src!=null))
    {
        src = VisualTreeHelper.GetParent(src);
        cbi = src as ComboBoxItem;
    }
    if (cbi != null)
    {
        ComboBox cb = ItemsControl.ItemsControlFromItemContainer(cbi) as ComboBox;
        if (cb != null)
        {
            var container = cb.ContainerFromElement((DependencyObject)e.OriginalSource);
            if (container != null)
            {
                cb.SelectedItem = cb.ItemContainerGenerator.ItemFromContainer(container);
            }
        }
    }
}

解决相同问题的其他方法可以使用blend's behaviors 由于这里不值得解释的原因,我无法使用这些行为。