using attached events with caliburn micro Message.Attach

故事扮演 提交于 2019-11-27 20:42:34

finally I understand the problem and the solution. The problem is that system.windows.interactiviy.EventTrigger doesn't support attached events. Caliburn micro uses it for actions thus my attached event didn't work. The solution was to write a customized event trigger and use caliburn micro action in a explicit manner. the customized event trigger was taken from that post:http://joyfulwpf.blogspot.com/2009/05/mvvm-invoking-command-on-attached-event.html?showComment=1323674885597#c8041424175408473805

 public class RoutedEventTrigger : EventTriggerBase<DependencyObject>
{
    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; }
}

and then when you want to use caliburn action:

<i:Interaction.Triggers>
                <!--in the routed event property you need to put the full name space and event name-->
                <Helpers:RoutedEventTrigger RoutedEvent="Helpers:DataChanging.Changing">
                    <cal:ActionMessage MethodName="SelectedDataChanged">
                        <cal:Parameter Value="$eventargs" />
                    </cal:ActionMessage>
                </Helpers:RoutedEventTrigger>
 </i:Interaction.Triggers>

I dont think that the parser for the shortened Message.Attach syntax supports attached events. But why don't you just add the ActionMessage directly to the Actions of the EventTrigger?

<EventTrigger RoutedEvent="Helpers:DataChanging.Changing">
    <EventTrigger.Actions>
        <!-- new part -->
        <cal:ActionMessage MethodName="SelectedDataChanged">  
            <cal:Parameter Value="$eventargs" />  
        </cal:ActionMessage>  
        <!-- /new part -->
        <BeginStoryboard x:Name="sb">
            <Storyboard x:Name="dsf">
                <Storyboard x:Name="myStoryboard">
                    <BooleanAnimationUsingKeyFrames Storyboard.TargetName="SSS" Storyboard.TargetProperty="IsChecked">
                        <DiscreteBooleanKeyFrame KeyTime="00:00:00" Value="False" />
                    </BooleanAnimationUsingKeyFrames>
                </Storyboard>
            </Storyboard>
        </BeginStoryboard>
    </EventTrigger.Actions>
</EventTrigger>

Have you tried this?

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

I needed to send an event from a child control to the parents ViewModel, and it worked fine for me. I'll post some example code maybe it'll help someone out!

Child Control codebehind:

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);
    }
}

Child control XAML:

<Button Grid.Row="1" Grid.Column="0"
        Content="Close Me!" Height="50"
        Click="Close" />

Parent view:

<userControls:MyControl cal:Message.Attach="[Event ControlClosed] = [Action ClosePopup]" />
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!