如何在WPF中的ViewModel中绑定Drop和PreviewMouseLeftButtonDown事件

时间:2018-07-17 08:56:12

标签: c# wpf xaml mvvm mouseevent

我必须在ViewModel中绑定Grid Drop事件和PreviewMouseLeftButtonDown事件。我有一个RelayCommand。但这仅是为了传递对象而完成的,我必须使用命令以及MouseButtonEventArgs传递路由事件。我的示例代码如下,请提出在视图模型中使用路由事件args和MouseButtonEventArgs的任何建议。

            <Grid
                x:Name="mainGrid"                    
                AllowDrop="True"
                Background="#F0F0F0">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="Drop">
                        <cmd:EventCommandExecuter Command="{Binding GridDrop}" />
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </Grid>
<Grid Background="LightBlue" PreviewMouseLeftButtonDown="Grid_PreviewMouseLeftButtonDown">

EventCommandExecuter

public class EventCommandExecuter : TriggerAction<DependencyObject>
{
    #region Constructors

    public EventCommandExecuter()
        : this(CultureInfo.CurrentCulture)
    {
    }

    public EventCommandExecuter(CultureInfo culture)
    {
        Culture = culture;
    }

    #endregion

    #region Properties

    #region Command

    public ICommand Command
    {
        get { return (ICommand)GetValue(CommandProperty); }
        set { SetValue(CommandProperty, value); }
    }

    public static readonly DependencyProperty CommandProperty =
        DependencyProperty.Register("Command", typeof(ICommand), typeof(EventCommandExecuter), new PropertyMetadata(null));

    #endregion

    #region EventArgsConverterParameter

    public object EventArgsConverterParameter
    {
        get { return (object)GetValue(EventArgsConverterParameterProperty); }
        set { SetValue(EventArgsConverterParameterProperty, value); }
    }

    public static readonly DependencyProperty EventArgsConverterParameterProperty =
        DependencyProperty.Register("EventArgsConverterParameter", typeof(object), typeof(EventCommandExecuter), new PropertyMetadata(null));

    #endregion

    public IValueConverter EventArgsConverter { get; set; }

    public CultureInfo Culture { get; set; }

    #endregion

    protected override void Invoke(object parameter)
    {
        var cmd = Command;

        if (cmd != null)
        {
            var param = parameter;

            if (EventArgsConverter != null)
            {
                param = EventArgsConverter.Convert(parameter, typeof(object), EventArgsConverterParameter, CultureInfo.InvariantCulture);
            }

            if (cmd.CanExecute(param))
            {
                cmd.Execute(param);
            }
        }
    }
}

我想像下面那样在viewmodel中传递对象和RoutedEventArgs。请帮助

public void Grid_Drop(object sender, RoutedEventArgs e)
{
}    

1 个答案:

答案 0 :(得分:0)

我觉得对于这样简单的任务,命令通常过于矫kill过正。 您可以像这样在视图背后的代码中简单地声明ViewModel:

    public partial class MainWindow : Window
    {
        private ViewModel _vm;
        public ViewModel Vm
        {
            get { return _vm;}
            set
            {
                _vm = value ;                
            }
        }
        //....Constructor here.... 
      }

然后创建一个公共事件:

public event RoutedEventHandler OnGridDrop;

并调用它:

public void Grid_Drop(object sender, RoutedEventArgs e)
{
    OnGridDrop?.Invoke(sender,e)
}    

现在您只需要初始化ViewModel:

public MainWindow()
{     
    InitializeComponent();
    Vm = new ViewModel();
    OnGridDrop += Vm.OnGridDrop;
}

并订阅您在ViewModel中声明的相应处理程序。