[英]WPF MVVM - How do I get the mouse coordinates on a Canvas?
I have a window with a canvas (that is smaller than the window itself).我有一个 window 和一个 canvas(比 window 本身小)。 Now I want to draw a rectangle whenever I click on the canvas, and it should appear where I clicked.
现在我想在单击 canvas 时绘制一个矩形,它应该出现在我单击的位置。 I got it working, but whenever I click on an existing rectangle, it seems to take the mouse coordinates relative to the upper left corner of the existing rectangle and not of the canvas itself.
我让它工作了,但是每当我点击一个现有的矩形时,它似乎采用的是相对于现有矩形左上角的鼠标坐标,而不是 canvas 本身的坐标。 Below you see my XAML:
下面你会看到我的 XAML:
<ItemsControl ItemsSource="{Binding CanvasItems}" Grid.Column="1" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Background="White">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<i:InvokeCommandAction Command="{Binding MouseButtonDownCommand}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Canvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="Shape">
<Setter Property="Canvas.Left" Value="{Binding ModelLeft}"/>
<Setter Property="Canvas.Top" Value="{Binding ModelTop}"/>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
And here you can see the according command method in my ViewModel:在这里您可以在我的 ViewModel 中看到相应的命令方法:
private void OnMouseButtonDown(object obj)
{
var mouseArgs = obj as MouseButtonEventArgs;
var point = mouseArgs.GetPosition((IInputElement)mouseArgs.Source);
ModelLeft = (int)point.X;
ModelTop = (int)point.Y;
Rectangle rect = new Rectangle();
rect.Stroke = new SolidColorBrush(Colors.Black);
rect.Fill = new SolidColorBrush(Colors.Red);
rect.Width = 200;
rect.Height = 200;
CanvasItems.Add(rect);
}
For a better uderstanding, ModelLeft
and ModelTop
are two int properties and CanvasItems
is an ObservableCollection<object>
.为了更好地理解,
ModelLeft
和ModelTop
是两个 int 属性,而CanvasItems
是ObservableCollection<object>
。 Also, I'm using System.Windows.Shapes;
另外,我正在使用
System.Windows.Shapes;
for the rectangles.对于矩形。
How can I get it working as expected, that it will always take the mouse position relative to the canvas and not an already existing shape on the canvas?我怎样才能让它按预期工作,它总是会使用相对于 canvas 的鼠标 position 而不是 canvas 上已经存在的形状?
GetPosition
returns the mouse coordinates relative to the top-left angle of the element passed in. So rather than the Shape element hit and referred to by mouseArgs.Source
you likely just have to pass the canvas itself to mouseArgs.GetPosition. GetPosition
返回相对于传入元素左上角的鼠标坐标。因此,您可能只需将 canvas 本身传递给 mouseArgs.GetPosition,而不是点击并引用mouseArgs.Source
的 Shape 元素。
var point = mouseArgs.GetPosition(myCanvas);
Your could also make your rectangles "invisible" to the mouse clicks, so that the source of the event will always be your canvas.您还可以使您的矩形对鼠标单击“不可见”,这样事件的来源将始终是您的 canvas。
rect.Width = 200;
rect.Height = 200;
rect.IsHitTestVisible = false;
Also, mouse clicks come in both bubbling and tunneling versions, and to catch the tunneling version, handle the PreviewMouseDown event.此外,鼠标点击有冒泡和隧道版本,要捕捉隧道版本,请处理 PreviewMouseDown 事件。 That way, the canvas will always have a chance to handle the event first.
这样,canvas 将始终有机会首先处理该事件。 But, you will still have to have the canvas object as a parameter in your GetPosition call.
但是,您仍然必须在 GetPosition 调用中将 canvas object 作为参数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.