问题
I like the functionality of IsMouseDirectlyOverChanged, but it only works for the topmost elements. What I really want to do is monitor the IsMouseOver property of a control, regardless of its z-index, and receive notification when IsMouseOver is modified. If I owned this property, I could do INotifyPropertyChanged, but unfortunately it's owned by UIElement. Still learning the ropes of WPF, so maybe this is easy, but I'm not familiar with how to monitor properties that belong to parent classes. Unlike IsMouseDirectlyOver, IsMouseOver doesn't have a changed event attached.
回答1:
You can use styles to react to when IsMouseOver is changed.
<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>
And later attach the style to an element:
<Rectangle Style="{StaticResource RecStyle}" Width="100" Height="100" Fill="Black" />
Edit:
If you want to call code from within a style, the solution is rather complex.
First, you have to create a custom UserControl class and give it an attached property. Whenever the attached property is changed, you can use the property changed callback. Here's the *.xaml.cs
file, just keep the default .xaml
file:
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();
}
}
}
You'll then have to wrap the elements you want to react to in your custom control and make the style change the attached property of that custom control. Example:
<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>
Add all your code into the OnMouseOverIsChanged
function, and this should work.
回答2:
I see there is an accepted solution, I just wanted to share my opinion. In my case I have a Label in a Usercontrol and I needed to react on Mouse is over. For me the MouseEnter and MouseLeave events fire, so I can handle them. I have the label defined in Code Behind (since I place it programatically on runtime) and just added standard Events of the label object. IsMouseDirectlyOverChanged did not work for me, since I'm hovering over the Usercontrol. This also works if there is another Control overlapping. So maybe this doesn't fit your situation, maybe it does :-)
I wanted to paste the xaml as well, but it seems I didn't get the markdown-thing :-)
... Private Sub Rectangle1_MouseEnter(sender As Object, e As System.Windows.Input.MouseEventArgs) Handles Rectangle1.MouseEnter, Rectangle2.MouseEnter Dim s As Rectangle = sender s.Fill = Brushes.Red End Sub Private Sub Rectangle1_MouseLeave(sender As Object, e As System.Windows.Input.MouseEventArgs) Handles Rectangle1.MouseLeave, Rectangle2.MouseLeave Dim s As Rectangle = sender s.Fill = Brushes.Green End Sub ...
BR, D
来源:https://stackoverflow.com/questions/10985993/how-do-i-create-handle-ismouseoverchanged