代码之家  ›  专栏  ›  技术社区  ›  Shane

重写WPF组合框中的鼠标悬停行为

  •  0
  • Shane  · 技术社区  · 15 年前

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

    3 回复  |  直到 13 年前
        1
  •  2
  •   Quartermeister    15 年前

    您可以通过重写onmousemove来完成。这个 OriginalSource mouseEventargs的属性将为您提供鼠标正下方的元素。你可以使用 ContainerFromElement 获取包含该元素的ComboBox项,然后 ItemContainerGenerator.ItemFromContainer 要获取要选择的项目:

    protected override void OnMouseMove(MouseEventArgs e)
    {
        base.OnMouseMove(e);
        var container = ContainerFromElement((DependencyObject)e.OriginalSource);
        if (container != null)
        {
            SelectedItem = ItemContainerGenerator.ItemFromContainer(container);
        }
    }
    
        2
  •  0
  •   Wallstreet Programmer    15 年前

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

        3
  •  0
  •   FabioDch    13 年前

    这就是我在代码中解决同一个问题的方法,希望它对其他人有用,或者只是朝着完整的XAML解决方案迈出的一步。

    我遵循四分之一的解决方案。但在我看来,需要子类化组合框是一个设计缺陷(因为这样做只是为了处理mouseover事件)。因为我只需要对mouseover事件的不同行为进行处理,所以在附加到xaml文件的类中,我只实现了处理mouseover事件的方法。

    首先,我用了 EventSetter 类,它是setter类的子类,并且是特定于事件的。因此,eventsetter可以像我们通常使用setter那样用于修饰frameworkelements。

    <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 因为这里不值得解释的原因,我不能使用这种行为。