我有一个有事件的自定义控件。 我有一个使用该自定义控件的窗口。 该窗口绑定到视图模型。 我想将自定义控件中的事件直接发送到我的viewmodel上的ICommand。 我显然在这里很密集,因为我无法弄清楚如何做到这一点。非常欢迎任何帮助。
由于
答案 0 :(得分:2)
如果是一次性的,你可以使用一个简单的事件处理程序:
<some:CustomControl SuperDuper="OnSuperDuper" />
代码隐藏
private void OnSuperDuper(object sender, EventArgs e)
{
_theCommand.Execute(null, (IInputElement)sender);
}
如果您想对特定事件多次执行此操作,我会使用附加属性。
<some:CustomControl my:AttachedEvents.SuperDuperCommand="{Binding TheCommand}" />
附加属性只是:
// use propa snippet to build this quickly
public static ICommand GetSuperDuperCommand(DependencyObject obj) { return (ICommand)obj.GetValue(SuperDuperCommandProperty); }
public static void SetSuperDuperCommand(DependencyObject obj, ICommand value) { obj.SetValue(SuperDuperCommandProperty, value); }
public static readonly DependencyProperty SuperDuperCommandProperty = DependencyProperty.RegisterAttached("SuperDuperCommand", typeof(ICommand), typeof(AttachedEvents), new PropertyMetadata
{
PropertyChangedCallback = (obj, e) =>
{
if(oldCommand==null) ((CustomControl)obj).SuperDuper += OnSuperDuper;
if(newCommand==null) ((CustomControl)obj).SuperDuper -= OnSuperDuper;
}
});
private void OnSuperDuper(object sender, EventArgs e)
{
var control = (CustomControl)sender;
GetSuperDuperCommand(sender).Execute(null, sender));
}
您可以进一步概括这一点,使用MarkupExtension将任何事件映射到任何命令。这是个主意:
<some:CustomControl SuperDuper="{lib:CommandWrapper {Binding TheCommand}}" />
代码是这样的:
public class CommandWrapper : MarkupExtension
{
public BindingBase CommandBinding { get; set; }
public CommandWrapper() {}
public CommandWrapper(BindingBase commandBinding) { CommandBinding = commandBinding; }
public object ProvideValue(IServiceProvider serviceProvider)
{
return new EventHandler((obj, e) =>
{
// Evaluate CommandBinding against obj, fire command
});
}
}
你可以充实细节。请注意,您可能希望将实际的事件处理程序类型传递给CommandWrapper,并使用反射来构造适当的委托,而不是简单地说“new EventHandler”。
我不完全确定XAML解析器是否允许您使用MarkupExtension设置事件,因此最后一个解决方案实际上可能无法正常工作。但如果没有,它可以与附加属性组合,如下:
<some:CustomControl lib:CommandWrapper.Add="{lib:CommandWrapper SuperDuper,{Binding TheCommand}}" />
这肯定会有效:CommandWrapper.Add将从标记扩展创建的CommandWrapper接收事件名称,并可以创建适当的映射。
答案 1 :(得分:-1)
如果要将事件路由到命令,可以使用附加属性。我使用此示例为ComboBox SelectionChanged事件添加命令支持:
http://blog.fossmo.net/post/How-to-create-an-attached-property-in-WPF-using-a-ComboBox.aspx
干杯。