WPF MVVM场景下,如何让EventToCommand同时传递事件Sender与参数?
解决MVVM中通过EventToCommand获取事件Sender的问题
方法1:利用MouseButtonEventArgs的Source属性
你绑定的PreviewMouseDown事件参数是MouseButtonEventArgs,它的Source属性就是触发事件的注册控件(也就是你要的Sender),无需修改现有XAML,直接在命令处理逻辑中获取即可:
public ICommand CanvasClick => new DelegateCommand<MouseButtonEventArgs>(args => { var senderCanvas = args.Source as Canvas; if (senderCanvas != null) { // 获取点击位置 var clickPosition = args.GetPosition(senderCanvas); // 执行你的业务逻辑 } });
注意:如果Canvas内嵌套了其他控件,
OriginalSource可能指向子元素,此时用Source更准确,因为它始终指向注册事件的根Canvas(即你的cnvLeft)。
方法2:通过MultiBinding同时传递Sender与EventArgs
如果担心Source属性不符合预期,可以通过多值绑定,把Canvas控件和事件参数一起传递给命令:
第一步:定义参数封装类与转换器
// 用于封装Sender和事件参数的类 public class CanvasClickParams { public Canvas Sender { get; set; } public MouseButtonEventArgs EventArgs { get; set; } } // 多值转换器,将两个参数合并为封装对象 public class ArgsAndSenderConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { return new CanvasClickParams { Sender = values[0] as Canvas, EventArgs = values[1] as MouseButtonEventArgs }; } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { throw new NotImplementedException(); } }
第二步:修改XAML绑定
<Canvas x:Name="cnvLeft"> <Canvas.Resources> <local:ArgsAndSenderConverter x:Key="ArgsAndSenderConverter"/> </Canvas.Resources> <i:Interaction.Triggers> <i:EventTrigger EventName="PreviewMouseDown"> <cmd:EventToCommand Command="{Binding CanvasClick}"> <cmd:EventToCommand.CommandParameter> <MultiBinding Converter="{StaticResource ArgsAndSenderConverter}"> <Binding ElementName="cnvLeft"/> <Binding RelativeSource="{RelativeSource Self}" Path="EventArgs"/> </MultiBinding> </cmd:EventToCommand.CommandParameter> </cmd:EventToCommand> </i:EventTrigger> </i:Interaction.Triggers> </Canvas>
第三步:处理命令参数
public ICommand CanvasClick => new DelegateCommand<CanvasClickParams>(param => { if (param == null || param.Sender == null || param.EventArgs == null) return; var clickPosition = param.EventArgs.GetPosition(param.Sender); // 执行你的业务逻辑 });
方法3:自定义EventToCommand行为
如果需要频繁实现类似需求,可以自定义一个行为,在触发事件时自动传递Sender和EventArgs。不过该方法相对复杂,适合通用场景复用。
内容的提问来源于stack exchange,提问作者Kevin99
相关产品推荐
相关产品推荐

