Search code examples
c#xamlmvvmwinui-3winui

WinUI 3 xaml how to pass Mouse position as command parameter


I would like to pass the mouse position as a commandparameter to my command that is executed on clicking a MenuFlyoutItem. Does anyone know how to do this? I would like to have the new item added to the 'Views' collection appear at the mouse position at the canvas. I know I can accomplish it in code-behind, but would like not to.


<controls1:CanvasView.ContextFlyout>
    <MenuFlyout>
        <MenuFlyoutItem Text="Add view" Command="{x:Bind ViewModel.AddViewCommand}" CommandParameter="{What to put here??}" />
    </MenuFlyout>
</controls1:CanvasView.ContextFlyout>

Solution

  • I guess you will need to keep track of the mouse position.

    For example:

    MainViewModel.cs

    public partial class MainViewModel : ObservableObject
    {
        [RelayCommand]
        private void AddView(Point point)
        {
        }
    }
    

    MainWindow.xaml.cs

    [ObservableObject]
    public sealed partial class MainWindow : Window
    {
        [ObservableProperty]
        private Point _mousePosition;
    
        private void RootGrid_PointerMoved(object sender, PointerRoutedEventArgs e)
        {
            PointerPoint point = e.GetCurrentPoint(this.RootGrid);
            MousePosition = point.Position;
        }
    
        public MainWindow()
        {
            this.InitializeComponent();
        }
    
        public ViewModel ViewModel { get; } = new();
    }
    

    **MainWindow.xaml

    <Window
        x:Class="MousePositionExample.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:local="using:MousePositionExample"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid
            x:Name="RootGrid"
            Background="Transparent"
            PointerMoved="RootGrid_PointerMoved">
            <Canvas Background="Transparent">
                <Canvas.ContextFlyout>
                    <MenuFlyout>
                        <MenuFlyoutItem
                            Command="{x:Bind ViewModel.AddViewCommand}"
                            CommandParameter="{x:Bind MousePosition, Mode=OneWay}"
                            Text="Add view" />
                    </MenuFlyout>
                </Canvas.ContextFlyout>
            </Canvas>
        </Grid>
    
    </Window>
    

    Note

    I'm using the CommunityToolkit.Mvvm NuGet package for the MVVM design.