How to get mouse cursor position in WPF MVVM applications using Dependency Properties

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 MainWindow.xaml [code language="xml"] <Window x:Class="MousePositionMvvm.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:MousePositionMvvm" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" mc:Ignorable="d" Title="MainWindow" Height="450" Width="525"> <Window.DataContext> <local:MainWindowViewModel /> </Window.DataContext> <Grid> <DockPanel> <StackPanel DockPanel.Dock="Top" Orientation="Horizontal"> <TextBlock Text="{Binding PanelX, StringFormat='X={0}'}" /> <TextBlock Text="{Binding PanelY, StringFormat='y={0}'}" /> </StackPanel> <Canvas DockPanel.Dock="Bottom" Background="Aqua"> <i:Interaction.Behaviors> <local:MouseBehaviour MouseX="{Binding PanelX, Mode=OneWayToSource}" MouseY="{Binding PanelY, Mode=OneWayToSource}" /> </i:Interaction.Behaviors> </Canvas> </DockPanel> </Grid> </Window> [/code] 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 MainWindowViewModel.cs [code language="csharp"] 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; } set { if (value.Equals(_panelX)) return; _panelX = value; OnPropertyChanged("PanelX"); } } public double PanelY { get { return _panelY; } set { if (value.Equals(_panelY)) return; _panelY = value; OnPropertyChanged("PanelY"); } } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { VerifyPropertyName(propertyName); var handler = PropertyChanged; handler?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } [Conditional("DEBUG")] private void VerifyPropertyName(string propertyName) { if (TypeDescriptor.GetProperties(this)[propertyName] == null) throw new ArgumentNullException(GetType().Name + " does not contain property: " + propertyName); } } } [/code] Step 4: Create an attached behaviour class MouseBehaviour.cs [code language="csharp"] 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; } } } [/code] 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.

Comments

Popular posts from this blog

Using the Supervisor Controller Pattern to access View controls in MVVM

Getting started with client-server applications in C++

How to send an e-mail via Google SMTP using C#