我已完成自定义图表控件,我想在光标后面绘制一个简单的十字。该图表在Canvas上实现为PolyLine,我在Canvas的OnMouseMove事件中绘制两条线来改变它们的坐标。
令人惊讶的是发现当MainGUI线程空闲时,事件只被调用每10秒左右事件(UI完全响应,如果我暂停应用程序主线程在App mainForm.ShowDialog())
关于如何找到原因的任何想法都会发生?我使用OnMouseMove或PreviewOnMouseMove获得相同的性能。
编辑:这是我画十字架的方式(无论如何,如果我在OnMouseMove上放置一个断点,它只会不时停止)。
XAML:
<Border BorderThickness="1" BorderBrush="White" Grid.Column="1" Grid.Row="0" Grid.RowSpan="2" Grid.ColumnSpan="2" >
<Canvas x:Name="DrawArea" PreviewMouseMove="DrawArea_PreviewMouseMove" />
</Border>
CS:
public Chart()
{
_line = new Polyline();
_line.Stroke = Brushes.Orange;
_crossX = new Line();
_crossY = new Line();
_crossX.Stroke = Brushes.Orange;
_crossY.Stroke = Brushes.Orange;
_crossX.StrokeThickness = 1;
_crossY.StrokeThickness = 1;
InitializeComponent();
this.DrawArea.Children.Add(_line);
this.DrawArea.Children.Add(_crossX);
this.DrawArea.Children.Add(_crossY);
}
private void DrawArea_MouseMove(object sender, MouseEventArgs e)
{
Point mousePosition = System.Windows.Input.Mouse.GetPosition(this.DrawArea);
_crossX.X1 = 0;
_crossX.X2 = this.DrawArea.ActualWidth;
_crossX.Y1 = _crossX.Y2 = mousePosition.Y;
_crossY.Y1 = 0;
_crossY.Y2 = this.DrawArea.ActualHeight;
_crossY.X1 = _crossY.X2 = mousePosition.X;
}
答案 0 :(得分:26)
这很奇怪,我不知道为什么......
FrameworkElement.MouseMove
仅在区域有一些明确的背景画笔\填充集时才有效。
在您设置Canvas.Background="Transparent"
的情况下,它应该有效。
还有另一个解决方法...... WPF Not sending MouseMove events after CaptureMouse();
这可能是因为HitTest
取决于彩色像素及其反馈。
无论是什么,它都没有在MSDN上记录,并且让许多UI设计者感到困惑。
答案 1 :(得分:0)
我最终编写了这样的鼠标全局鼠标处理程序:
using System.Windows.Interop;
private const int WM_MOUSEMOVE = 0x0200;
public delegate void Del_MouseMovedEvent(Point mousePosition);
// Relative to this control, the mouse position will calculated
public IInputElement Elmt_MouseMovedRelativeElement = null;
// !! This is static; needs special treatment in a multithreaded application !!
public static event Del_MouseMovedEvent Evt_TheMouseMoved = null;
// your main function call
public MyMainWindows()
{
// install the windows message filter first
ComponentDispatcher.ThreadFilterMessage += ComponentDispatcher_ThreadFilterMessage;
InitializeComponent();
...
}
// filtering the windows messages
private void ComponentDispatcher_ThreadFilterMessage(ref MSG msg, ref bool handled)
{
if(msg.message == WM_MOUSEMOVE)
{
this.Evt_TheMouseMoved?.Invoke(Mouse.GetPosition(this.Elmt_MouseMovedRelativeElement));
}
}
// individual event for mouse movement
private void MyMouseMove(Point mousePoint)
{
// called on every mouse move when event is assigned
Console.WriteLine(mousePoint.X + " " + mousePoint.Y);
}
private void AnyFunctionDeeperInTheCode()
{
// assign the handler to the static var of the main window
MyMainWindows.Evt_TheMouseMoved += MyMouseMove;
// set the element / control to which the mouse position should be calculated;
MyMainWindows.Elmt_MouseMovedRelativeElement = this;
...
// undassign the handler from the static var of the main window
MyMainWindows.Evt_TheMouseMoved -= MyMouseMove;
}