wpf window mousedown implemented in mvvm as command via behavior

 public static class MouseBehavior
 {
     public static readonly DependencyProperty MouseDownCommandProperty =
         DependencyProperty.RegisterAttached("MouseDownCommand",
             typeof(ICommand),
             typeof(MouseBehavior),
             new PropertyMetadata(null, OnMouseDownCommandChanged));


     public static void SetMouseDownCommand(DependencyObject dObj, ICommand commandValue)
     {
         dObj.SetValue(MouseDownCommandProperty, commandValue);
     }

     public static ICommand GetMouseDownCommand(DependencyObject dObj)
     {
         return (ICommand)dObj.GetValue(MouseDownCommandProperty);
     }

     private static void OnMouseDownCommandChanged(DependencyObject dObj, DependencyPropertyChangedEventArgs e)
     {
         if (dObj is UIElement element)
         {
             if (e.NewValue != null)
             {
                 element.MouseDown += Element_MouseDown;
             }
             else
             {
                 element.MouseDown -= Element_MouseDown;
             }
         }
     }

     private static void Element_MouseDown(object sender, MouseButtonEventArgs e)
     {
         var element = sender as UIElement;
         if (element != null)
         {
             var command = GetMouseDownCommand(element);
             if (command?.CanExecute(e) == true)
             {
                 command.Execute(e);
             }
         }
     }
 }


<Window x:Class="WpfApp202.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:WpfApp202"
        xmlns:behavior="http://schemas.microsoft.com/xaml/behaviors"
        mc:Ignorable="d"
        WindowState="Maximized"
        Title="MainWindow" Height="450" Width="800"
        local:MouseBehavior.MouseDownCommand="{Binding WindowMouseDownCommand}">
    <Grid>
</Grid>
</Window>





//vm
public DelCommand WindowMouseDownCommand { get; set; }
WindowMouseDownCommand = new DelCommand(MouseDownCommandExecuted, MouseDownCommandCanExecute);


        private bool MouseDownCommandCanExecute(object? obj)
        {
            return true;
        }

        private int itemsCount = 0;
        private int idx = 0;
        private void MouseDownCommandExecuted(object? obj)
        {
            if (obj != null && obj is MouseEventArgs e)
            {
                var pos = e.GetPosition(null);
                string str = $"{++idx},X:{pos.X},Y:{pos.Y}";
                PosStrList.Add(str);
                itemsCount = PosStrList.Count;
                SelectedItem = PosStrList[itemsCount - 1];
            }
        }

 

 

 

 

 

 

 

 

//xaml
<Window x:Class="WpfApp202.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:WpfApp202"
        xmlns:behavior="http://schemas.microsoft.com/xaml/behaviors"
        mc:Ignorable="d"
        WindowState="Maximized"
        Title="{Binding SelectedItem,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
        Height="450" Width="800"
        local:MouseBehavior.MouseDownCommand="{Binding WindowMouseDownCommand}">
    <Grid>
        <ListBox Width="500"
                HorizontalAlignment="Left"
                VerticalAlignment="Stretch"
                SelectedItem="{Binding SelectedItem,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                ItemsSource="{Binding PosStrList,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
            <behavior:Interaction.Triggers>
                <behavior:EventTrigger EventName="SelectionChanged">
                    <behavior:InvokeCommandAction Command="{Binding SelectionChangedCommand}"
                                                  CommandParameter="{Binding  RelativeSource={RelativeSource Mode=FindAncestor,
                        AncestorType={x:Type ListBox}}}"/>
                </behavior:EventTrigger>
            </behavior:Interaction.Triggers>
            <ListBox.ItemContainerStyle>
                <Style TargetType="{x:Type ListBoxItem}">
                    <Setter Property="FontSize" Value="20"/>
                    <Style.Triggers>
                        <Trigger Property="IsSelected" Value="True">
                            <Setter Property="FontSize" Value="50"/>
                            <Setter Property="Foreground" Value="Red"/>
                        </Trigger>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="FontSize" Value="50"/>
                            <Setter Property="Foreground" Value="Blue"/>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </ListBox.ItemContainerStyle>
        </ListBox>
    </Grid>
</Window>



//cs
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp202
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            var vm = new MainVM();
            this.DataContext = vm;
        }

        private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {

        }
    }


    public class MainVM : INotifyPropertyChanged
    {
        public MainVM()
        {
            PosStrList = new ObservableCollection<string>();
            WindowMouseDownCommand = new DelCommand(MouseDownCommandExecuted, MouseDownCommandCanExecute);
            SelectionChangedCommand = new DelCommand(SelectionChangedCommandExecuted, SelectionChangedCommandCanExecute);
        }

        private bool SelectionChangedCommandCanExecute(object? obj)
        {
            return true;
        }

        private void SelectionChangedCommandExecuted(object? obj)
        {
            if(obj!=null)
            {
                Application.Current?.Dispatcher.BeginInvoke(new Action(() =>
                {
                    var lbx = obj as ListBox;
                    if (lbx != null)
                    {
                        lbx.ScrollIntoView(lbx.Items[itemsCount - 1]);
                    }
                }));                
            }
        }

        public DelCommand WindowMouseDownCommand { get; set; }
        public DelCommand SelectionChangedCommand { get; set; }

        public event PropertyChangedEventHandler? PropertyChanged;
        private void OnPropertyChanged([CallerMemberName] string propName = "")
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler?.Invoke(this, new PropertyChangedEventArgs(propName));
            }
        }

        private string selectedItem;
        public string SelectedItem
        {
            get
            {
                return selectedItem;
            }
            set
            {
                if (value != selectedItem)
                {
                    selectedItem = value;
                    OnPropertyChanged(nameof(SelectedItem));
                }
            }
        }


        private ObservableCollection<string> posStrList;
        public ObservableCollection<string> PosStrList
        {
            get
            {
                return posStrList;
            }
            set
            {
                if (value != posStrList)
                {
                    posStrList = value;
                    OnPropertyChanged(nameof(PosStrList));
                }
            }
        }

        //private ICommand mouseDownCommand;
        //public ICommand MouseUpCommand
        //{
        //    get
        //    {
        //        if(mouseDownCommand == null)
        //        {
        //            mouseDownCommand = new DelCommand(MouseUpCommandExecuted, MouseUpCommandCanExecute);
        //        }
        //        return mouseDownCommand;
        //    }
        //}

        private bool MouseDownCommandCanExecute(object? obj)
        {
            return true;
        }

        private int itemsCount = 0;
        private int idx = 0;
        private void MouseDownCommandExecuted(object? obj)
        {
            if (obj != null && obj is MouseEventArgs e)
            {
                var pos = e.GetPosition(null);
                string str = $"{++idx},X:{pos.X},Y:{pos.Y}";
                PosStrList.Add(str);
                itemsCount = PosStrList.Count;
                SelectedItem = PosStrList[itemsCount - 1];
            }
        }
    }

    public static class MouseBehavior
    {
        public static readonly DependencyProperty MouseDownCommandProperty =
            DependencyProperty.RegisterAttached("MouseDownCommand",
                typeof(ICommand),
                typeof(MouseBehavior),
                new PropertyMetadata(null, OnMouseDownCommandChanged));


        public static void SetMouseDownCommand(DependencyObject dObj, ICommand commandValue)
        {
            dObj.SetValue(MouseDownCommandProperty, commandValue);
        }

        public static ICommand GetMouseDownCommand(DependencyObject dObj)
        {
            return (ICommand)dObj.GetValue(MouseDownCommandProperty);
        }

        private static void OnMouseDownCommandChanged(DependencyObject dObj, DependencyPropertyChangedEventArgs e)
        {
            if (dObj is UIElement element)
            {
                if (e.NewValue != null)
                {
                    element.MouseDown += Element_MouseDown;
                }
                else
                {
                    element.MouseDown -= Element_MouseDown;
                }
            }
        }

        private static void Element_MouseDown(object sender, MouseButtonEventArgs e)
        {
            var element = sender as UIElement;
            if (element != null)
            {
                var command = GetMouseDownCommand(element);
                if (command?.CanExecute(e) == true)
                {
                    command.Execute(e);
                }
            }
        }
    }



    public class DelCommand : ICommand
    {
        private Action<object?> execute;
        private Predicate<object?> canExecute;
        public DelCommand(Action<object?> executeValue, Predicate<object?> canExecuteValue)
        {
            execute = executeValue;
            canExecute = canExecuteValue;
        }

        public event EventHandler? CanExecuteChanged
        {
            add
            {
                CommandManager.RequerySuggested += value;
            }
            remove
            {
                CommandManager.RequerySuggested -= value;
            }
        }

        public bool CanExecute(object? parameter)
        {
            if (canExecute == null)
            {
                return true;
            }
            return canExecute(parameter);
        }

        public void Execute(object? parameter)
        {
            execute(parameter);
        }
    }
}

 

posted @ 2025-04-13 14:45  FredGrit  阅读(24)  评论(0)    收藏  举报