I have a window with a canvas (that is smaller than the window itself). Now I want to draw a rectangle whenever I click on the canvas, and it should appear where I clicked. 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. Below you see my 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:
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>
.
Also, I'm using 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?