【问题标题】:Overriding mouse over behaviour in WPF combo box覆盖 WPF 组合框中的鼠标悬停行为
【发布时间】:2011-03-21 21:34:43
【问题描述】:

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

【问题讨论】:

    标签: wpf .net-3.5 wpf-controls


    【解决方案1】:

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

    【讨论】:

      【解决方案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);
          }
      }
      

      【讨论】:

        【解决方案3】:

        这就是我在代码中解决相同问题的方法,希望它对其他人有用,或者只是迈向完整 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 由于不值得在这里解释的原因,我无法使用这种行为。

        【讨论】:

          猜你喜欢
          • 2012-07-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-12-06
          • 2021-10-08
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多