下面的WPF程序会显示一个如下所示的窗口:
黑色方块外的鼠标移动会导致窗口标题更新为鼠标位置。当鼠标进入正方形时,更新停止。
即使鼠标悬停在方块上,我也希望MouseMove
继续触发。有没有办法做到这一点?
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace Wpf_Particle_Demo
{
class DrawingVisualElement : FrameworkElement
{
public DrawingVisual visual;
public DrawingVisualElement() { visual = new DrawingVisual(); }
protected override int VisualChildrenCount { get { return 1; } }
protected override Visual GetVisualChild(int index) { return visual; }
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var canvas = new Canvas();
Content = canvas;
var element = new DrawingVisualElement();
canvas.Children.Add(element);
CompositionTarget.Rendering += (s, e) =>
{
using (var dc = element.visual.RenderOpen())
dc.DrawRectangle(Brushes.Black, null, new Rect(0, 0, 50, 50));
};
MouseMove += (s, e) => Title = e.GetPosition(canvas).ToString();
}
}
}
答案 0 :(得分:3)
到目前为止,最简单的方法是在窗口上使用“隧道”事件,即PreviewMouseDown。它首先被传递到窗口并在层次结构中向上运行。所以你在窗口中拥有的其他元素并不重要。在代码中:
public partial class Window1 : Window {
public Window1() {
InitializeComponent();
this.PreviewMouseMove += new MouseEventHandler(Window1_PreviewMouseMove);
}
void Window1_PreviewMouseMove(object sender, MouseEventArgs e) {
this.Title = e.GetPosition(this).ToString();
}
}
答案 1 :(得分:2)
您需要Capture鼠标才能让Canvas
继续回复MouseMove
事件,尝试这样的事情,只要鼠标会更新您的坐标按下
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var canvas = new Canvas();
Content = canvas;
var element = new DrawingVisualElement();
canvas.Children.Add(element);
CompositionTarget.Rendering += (s, e) =>
{
using (var dc = element.visual.RenderOpen())
dc.DrawRectangle(Brushes.Black, null, new Rect(0, 0, 50, 50));
};
Mouse.Capture(canvas);
MouseDown += (s, e) => Mouse.Capture((UIElement)s);
MouseMove += (s, e) => Title = e.GetPosition(canvas).ToString();
MouseUp += (s, e) => Mouse.Capture(null);
}
第二种方法
public MainWindow()
{
InitializeComponent();
var canvas = new Canvas();
Content = canvas;
DrawingVisualElement element = new DrawingVisualElement();
Grid myElement = new Grid();
canvas.Children.Add(myElement);
CompositionTarget.Rendering += (s, e) =>
{
using (var dc = element.visual.RenderOpen())
{
dc.DrawRectangle(Brushes.Black, null, new Rect(100, 0, 50, 50));
}
DrawingImage myImage = new DrawingImage(element.visual.Drawing);
myElement.Height = myImage.Height;
myElement.Width = myImage.Width;
myElement.Background = new ImageBrush(myImage);
};
MouseMove += (s, e) => Title = e.GetPosition(canvas).ToString();
}
使用挂钩请务必添加using System.Windows.Interop;
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var canvas = new Canvas();
Content = canvas;
var element = new DrawingVisualElement();
canvas.Children.Add(element);
CompositionTarget.Rendering += (s, e) =>
{
using (var dc = element.visual.RenderOpen())
{
dc.DrawRectangle(Brushes.Black, null, new Rect(0, 0, 50, 50));
}
};
this.SourceInitialized += new EventHandler(OnSourceInitialized);
}
void OnSourceInitialized(object sender, EventArgs e)
{
HwndSource source = (HwndSource)PresentationSource.FromVisual(this);
source.AddHook(new HwndSourceHook(HandleMessages));
}
IntPtr HandleMessages(IntPtr hwnd, int msg,IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == 0x200)
Title = Mouse.GetPosition(this).ToString(); // because I did not want to split the lParam into High/Low values for Position information
return IntPtr.Zero;
}
}
答案 2 :(得分:0)
答案非常简单。您只需要设置element.IsHitTestVisible = false;