How to get mouse cursor position in WPF MVVM applications

Very useful StackOverflow link, Mark Green‘s answer, from which I have borrowed heavily here, with one or two modifications in order to fully work in a Visual Studio 2015 environment.

Step 1: Create a new WPF project

Step 2: Create an example WPF window


<Window x:Class="MousePositionMvvm.MainWindow"
        Title="MainWindow" Height="450" Width="525">

        <local:MainWindowViewModel />

            <StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
                <TextBlock Text="{Binding PanelX, StringFormat='X={0}'}" />
                <TextBlock Text="{Binding PanelY, StringFormat='y={0}'}" />
            <Canvas DockPanel.Dock="Bottom" Background="Aqua">
                    <local:MouseBehaviour MouseX="{Binding PanelX, Mode=OneWayToSource}"
                                          MouseY="{Binding PanelY, Mode=OneWayToSource}" />

We will use this window to showcase how the mouse cursor position is constantly read and updated.

Step 3: Create the MVVM View Model class

We will use this class four our X/Y coordinate bindings


using System;
using System.ComponentModel;
using System.Diagnostics;

namespace MousePositionMvvm
   public class MainWindowViewModel : INotifyPropertyChanged
      private double _panelX;
      private double _panelY;

      public double PanelX
         get { return _panelX; }
            if (value.Equals(_panelX)) return;
            _panelX = value;

      public double PanelY
         get { return _panelY; }
            if (value.Equals(_panelY)) return;
            _panelY = value;

      public event PropertyChangedEventHandler PropertyChanged;

      protected void OnPropertyChanged(string propertyName)
         var handler = PropertyChanged;
         handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));

      private void VerifyPropertyName(string propertyName)
         if (TypeDescriptor.GetProperties(this)[propertyName] == null)
            throw new ArgumentNullException(GetType().Name + " does not contain property: " + propertyName);

Step 4: Create an attached behaviour class


using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interactivity;

namespace MousePositionMvvm
   public class MouseBehaviour : Behavior<Panel>
      public static readonly DependencyProperty MouseYProperty = DependencyProperty.Register(
         "MouseY", typeof(double), typeof(MouseBehaviour), new PropertyMetadata(default(double)));

      public static readonly DependencyProperty MouseXProperty = DependencyProperty.Register(
         "MouseX", typeof(double), typeof(MouseBehaviour), new PropertyMetadata(default(double)));

      public double MouseY
         get { return (double) GetValue(MouseYProperty); }
         set { SetValue(MouseYProperty, value); }

      public double MouseX
         get { return (double) GetValue(MouseXProperty); }
         set { SetValue(MouseXProperty, value); }

      protected override void OnAttached()
         AssociatedObject.MouseMove += AssociatedObjectOnMouseMove;

      private void AssociatedObjectOnMouseMove(object sender, MouseEventArgs mouseEventArgs)
         var pos = mouseEventArgs.GetPosition(AssociatedObject);
         MouseX = pos.X;
         MouseY = pos.Y;

      protected override void OnDetaching()
         AssociatedObject.MouseMove -= AssociatedObjectOnMouseMove;

Step 5: Add necessary references

In this example we need to add a reference to System.Windows.Interactivity.

This will allow us to continuously monitor the mouse position as it is being moved around the screen.

Right-click your References folder and select Add reference…

Step 6: Try it

Observe how mouse coordinate position is continuously updated:

NOTE: this does not have to be a canvas control – it can be any control you like (eg Button) and of any size, so long as this is specified in the attached behaviour class also.

Leave a Reply