【问题标题】:How do I create/handle IsMouseOverChanged如何创建/处理 IsMouseOverChanged
【发布时间】:2012-06-14 16:56:12
【问题描述】:

我喜欢 IsMouseDirectlyOverChanged 的​​功能,但它只适用于最顶层的元素。我真正想做的是监视控件的 IsMouseOver 属性,而不管它的 z-index,并在 IsMouseOver 被修改时接收通知。如果我拥有这个属性,我可以执行 INotifyPropertyChanged,但不幸的是它归 UIElement 所有。仍在学习 WPF 的原理,所以这可能很容易,但我不熟悉如何监视属于父类的属性。与 IsMouseDirectlyOver 不同,IsMouseOver 没有附加更改事件。

【问题讨论】:

    标签: wpf events properties mouse


    【解决方案1】:

    我看到有一个公认的解决方案,我只是想分享我的意见。在我的情况下,我在用户控件中有一个标签,我需要对鼠标结束做出反应。对我来说,MouseEnter 和 MouseLeave 事件会触发,所以我可以处理它们。我在后面的代码中定义了标签(因为我以编程方式将它放在运行时),并且刚刚添加了标签对象的标准事件。 IsMouseDirectlyOverChanged 对我不起作用,因为我将鼠标悬停在用户控件上。如果有另一个 Control 重叠,这也有效。因此,也许这不适合您的情况,也许可以:-)
    我也想粘贴 xaml,但似乎我没有得到 markdown-thing :-)

    ... Private Sub Rectangle1_MouseEnter(sender As Object, e As System.Windows.Input.MouseEventArgs) 处理 Rectangle1.MouseEnter, Rectangle2.MouseEnter Dim s As Rectangle = 发件人 s.Fill = Brushes.Red 结束子 Private Sub Rectangle1_MouseLeave(sender As Object, e As System.Windows.Input.MouseEventArgs) 处理 Rectangle1.MouseLeave, Rectangle2.MouseLeave Dim s As Rectangle = 发件人 s.Fill = Brushes.Green 结束子 ...

    BR, D

    【讨论】:

    • MouseEnterMouseLeave 在我嵌套在 TabControl 中的子视图中为我工作得很好 - 我估计也很好。我不知道为什么他们不会为 OP 或任何其他用户工作,只要 z-index 没有任何问题,这必须由程序员实现 - 而不仅仅是凭借处于用户控件或嵌套视图中。如果他希望能够将鼠标悬停在其他东西后面/下面的东西上并在其上引发和事件,您只需将 MouseEnterMouseLeave 放在顶部控件上即可。
    【解决方案2】:

    您可以使用样式来响应 IsMouseOver 何时更改。

    <Window.Resources>
         <Style x:Key="RectStyle" TargetType="Rectangle">
              <Style.Triggers>
                   <Trigger Property="IsMouseOver" Value="True">
                        <!-- react to property change here -->
                   </Trigger>
              </Style.Triggers>
         </Style>
     </Window.Resources>
    

    然后将样式附加到元素上:

    <Rectangle Style="{StaticResource RecStyle}" Width="100" Height="100" Fill="Black" />
    

    编辑:

    如果您想从样式中调用代码,则解决方案相当复杂。

    首先,您必须创建一个自定义 UserControl 类并为其提供附加属性。每当附加属性发生更改时,您都可以使用属性更改回调。这是*.xaml.cs文件,保留默认的.xaml文件即可:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace ExampleApp
    {
        /// <summary>
        /// Interaction logic for MouseOverWrapper.xaml
        /// </summary>
        public partial class MouseOverWrapper : UserControl
        {
    
            public static readonly DependencyProperty MouseIsOverProperty;
    
            static MouseOverWrapper()
            {
                MouseIsOverProperty = DependencyProperty.RegisterAttached(
                    "MouseIsOver", typeof(bool), typeof(MouseOverWrapper),
                    new FrameworkPropertyMetadata(false, OnMouseIsOverChanged));
            }
    
            public static bool GetMouseIsOver(UIElement element)
            {
                return (bool)element.GetValue(MouseIsOverProperty);
            }
    
            public static void SetMouseIsOver(UIElement target, bool value)
            {
                target.SetValue(MouseIsOverProperty, value);
            }
    
            private static void OnMouseIsOverChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                // handle code here. example:
                if ((bool)e.NewValue == true)
                    ((Rectangle)d).Fill = Brushes.Yellow;
                else
                    ((Rectangle)d).Fill = Brushes.Black;
            }
    
            public MouseOverWrapper()
            {
                InitializeComponent();
            }
        }
    }
    

    然后,您必须将要响应的元素包装在自定义控件中,并使样式更改该自定义控件的附加属性。示例:

    <Window x:Class="ExampleApp.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:ExampleApp"
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
            <Style x:Key="RecStyle" TargetType="Rectangle">
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="local:MouseOverWrapper.MouseIsOver" Value="True" />
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Window.Resources>
        <local:MouseOverWrapper>
            <Rectangle Style="{StaticResource RecStyle}" Width="100" Height="100" Fill="Black" />
        </local:MouseOverWrapper>
    </Window>
    

    将所有代码添加到OnMouseOverIsChanged 函数中,这应该可以工作。

    【讨论】:

    • 不幸的是,除非元素位于顶部,否则 MouseEnter 和 MouseLeave 不会触发。但我的理解是 IsMouseOver 的变化与 z-index 无关。所以这不能满足我的需要。
    • 这就是您要找的东西吗?如果不是,请准确说明您要做什么。
    • 谢谢。当 IsMouseOver 被触发时,我想在代码隐藏中处理事件。我可以在“”里面放什么来做到这一点?
    • 我刚刚编辑了答案以显示如何。我的猜测是,有一个更简单的解决方案可以做你想做的事,但我的应该可以。
    • 是的,这很复杂。当 IsMouseOver 发生更改时接收通知怎么样,全部来自代码隐藏,而不涉及触发器?有什么方法可以以某种方式在 Rectangle 的 IsMouseOver 属性上使用 INotifyPropertyChanged 之类的东西?
    猜你喜欢
    • 1970-01-01
    • 2011-03-06
    • 1970-01-01
    • 2019-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-26
    • 1970-01-01
    相关资源
    最近更新 更多