使用附带事件与caliburn micro Message.Attach

我正在尝试使用caliburn micro消息来触发我创建的附加事件:

public static class DataChanging { public delegate void DataChangingEventHandler(object sender, DataChangingEventArgs e); public static readonly RoutedEvent ChangingEvent = EventManager.RegisterRoutedEvent("Changing", RoutingStrategy.Bubble, typeof(DataChangingEventHandler), typeof(DataChanging)); public static void AddChangingHandler(DependencyObject o, DataChangingEventHandler handler) { ((UIElement)o).AddHandler(DataChanging.ChangingEvent, handler); } public static void RemoveChangingHandler(DependencyObject o, DataChangingEventHandler handler) { ((UIElement)o).RemoveHandler(DataChanging.ChangingEvent, handler); } public static bool GetActivationMode(DependencyObject obj) { return (bool)obj.GetValue(ActivationModeProperty); } public static void SetActivationMode(DependencyObject obj, bool value) { obj.SetValue(ActivationModeProperty, value); } public static readonly DependencyProperty ActivationModeProperty = DependencyProperty.RegisterAttached("ActivationMode", typeof(bool), typeof(DataChanging), new FrameworkPropertyMetadata(false, HandleActivationModeChanged)); private static void HandleActivationModeChanged(DependencyObject target, DependencyPropertyChangedEventArgs e) { var dataGrid = target as XamDataGrid; if (dataGrid == null) // if trying to attach to something else than a datagrid, just ignore return; if ((bool)e.NewValue) { dataGrid.RecordDeactivating += selector_RecordDeactivating; } else { dataGrid.RecordDeactivating -= selector_RecordDeactivating; } } static void selector_RecordDeactivating(object sender, RecordDeactivatingEventArgs e) { var args = new DataChangingEventArgs(DataChanging.ChangingEvent,sender) { Data = ((DataRecord) e.Record).DataItem, ShouldCancelChange = false }; (sender as UIElement).RaiseEvent(args); e.Cancel = args.ShouldCancelChange; } } 

在XAML中我添加了以下行:

 cal:Message.Attach="[Helpers:DataChanging.Changing] = [Action SelectedDataChanged($eventArgs)]" 

助手引用正确的命名空间。 我还尝试了其他失败的版本(完整命名空间):

 cal:Message.Attach="[clr-namespace:RTF.Client.UI.Helpers.DataChanging.Changing] = [Action SelectedDataChanged($eventArgs)]" 

试图自己设置交互事件:

当我尝试添加一个普通的事件触发器时,一切运行良好,所以这不是我附加的事件声明:

               

我在这做错了什么? 无法附加附加事件并使用caliburn micro调用它?

最后我理解了问题和解决方案。 问题是system.windows.interactiviy.EventTrigger不支持附加事件。 Caliburn micro使用它进行操作,因此我附加的事件不起作用。 解决方案是编写自定义事件触发器并以明确的方式使用caliburn微动作。 自定义事件触发器来自该post: http : //joyfulwpf.blogspot.com/2009/05/mvvm-invoking-command-on-attached-event.html?showComment=1323674885597#c8041424175408473805

  public class RoutedEventTrigger : EventTriggerBase { RoutedEvent _routedEvent; public RoutedEvent RoutedEvent { get { return _routedEvent; } set { _routedEvent = value; } } public RoutedEventTrigger() { } protected override void OnAttached() { Behavior behavior = base.AssociatedObject as Behavior; FrameworkElement associatedElement = base.AssociatedObject as FrameworkElement; if (behavior != null) { associatedElement = ((IAttachedObject)behavior).AssociatedObject as FrameworkElement; } if (associatedElement == null) { throw new ArgumentException("Routed Event trigger can only be associated to framework elements"); } if (RoutedEvent != null) { associatedElement.AddHandler(RoutedEvent, new RoutedEventHandler(this.OnRoutedEvent)); } } void OnRoutedEvent(object sender, RoutedEventArgs args) { base.OnEvent(args); } protected override string GetEventName() { return RoutedEvent.Name; } } 

然后当你想使用校准动作时:

         

我不认为缩短的Message.Attach语法的解析器支持附加事件。 但是,为什么不直接将ActionMessage添加到EventTrigger的Actions中?

                   

你试过这个吗?

 cal:Message.Attach="[Event Changing] = [Action SelectedDataChanged($eventArgs)]" 

我需要从子控件向父母ViewModel发送一个事件,它对我来说很好。 我会发布一些示例代码,也许它会帮助别人!

儿童控制代码隐藏:

 public partial class MyControl : UserControl { public MyControl() { InitializeComponent(); } #region Routed Events public static readonly RoutedEvent ControlClosedEvent = EventManager.RegisterRoutedEvent( "ControlClosed", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyControl)); public event RoutedEventHandler ControlClosed { add { AddHandler(ControlClosedEvent, value); } remove { RemoveHandler(ControlClosedEvent, value); } } #endregion Routed Events private void Close(object sender, RoutedEventArgs e) { var rea = new RoutedEventArgs(ControlClosedEvent); RaiseEvent(rea); } } 

儿童控制XAML:

  

家长观点: