Search code examples
c#wpfxamldata-bindingmouse-position

WPF - how do I bind a control's position to the current mouse position?


Is there a way to bind to the mouse position in WPF in the XAML file? Or does that have to be done in code? I have a control inside a Canvas, and I just want the control to follow the mouse while the mouse cursor is inside the Canvas.

Thanks


EDIT:

OK, I figured it out a relatively easy way using the code-behind file. I added a MouseMove event handler on the Canvas, and then added:

    private void Canvas_MouseMove(object sender, MouseEventArgs e)
    {
        // Get the x and y coordinates of the mouse pointer.
        System.Windows.Point position = e.GetPosition(this);
        double pX = position.X;
        double pY = position.Y;

        // Sets the position of the image to the mouse coordinates.
        myMouseImage.SetValue(Canvas.LeftProperty, pX);
        myMouseImage.SetValue(Canvas.TopProperty, pY);
    }

using http://msdn.microsoft.com/en-us/library/ms746626.aspx as a guideline.


Solution

  • I tried to make a kind of decorator for this purpose. You wrap the object, mouse position above which you want to control and bind some control to decorator MousePosition property.

    public class MouseTrackerDecorator : Decorator
    {
        static readonly DependencyProperty MousePositionProperty;
        static MouseTrackerDecorator()
        {
            MousePositionProperty = DependencyProperty.Register("MousePosition", typeof(Point), typeof(MouseTrackerDecorator));
        }
    
        public override UIElement Child
        {
            get
            {
                return base.Child;
            }
            set
            {
                if (base.Child != null)
                    base.Child.MouseMove -= _controlledObject_MouseMove;
                base.Child = value;
                base.Child.MouseMove += _controlledObject_MouseMove;
            }
        }
    
        public Point MousePosition
        {
            get
            {
                return (Point)GetValue(MouseTrackerDecorator.MousePositionProperty);
            }
            set
            {
                SetValue(MouseTrackerDecorator.MousePositionProperty, value);
            }
        }
    
        void _controlledObject_MouseMove(object sender, MouseEventArgs e)
        {
            Point p = e.GetPosition(base.Child);
    
            // Here you can add some validation logic
            MousePosition = p;            
        }
    }
    

    and XAML

    <local:MouseTrackerDecorator x:Name="mouseTracker">
        <Canvas Width="200" Height="200" Background="Red">
            <Button Width="20" Height="20" Canvas.Left="{Binding ElementName=mouseTracker, Path=MousePosition.X}" Canvas.Top="{Binding ElementName=mouseTracker, Path=MousePosition.Y}"  />
        </Canvas>
    </local:MouseTrackerDecorator>