使用带有 caliburn micro Message.Attach 的附加事件 [英] using attached events with caliburn micro Message.Attach

查看:74
本文介绍了使用带有 caliburn micro Message.Attach 的附加事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to use caliburn micro message to trigger an attached event that I created:

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 本身中,我添加了以下行:

In the XAML itself I added the following line:

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

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

Helpers refer to the right namespace. I also tried other versions that failed (full namespace):

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

尝试自己设置交互事件:

tried to set the interaction event by myself:

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

When I tried adding a normal event trigger everything worked well, so it's not my attached event declaration :

 <EventTrigger RoutedEvent="Helpers:DataChanging.Changing">
                    <EventTrigger.Actions>
                        <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>

我在这里做错了什么?有没有办法附加一个附加的事件并使用 caliburn micro 调用它?

What am I doing wrong here? There is no way to attach an attached event and invoke it using caliburn micro?

推荐答案

终于明白问题所在和解决方案了.问题是 system.windows.interactiviy.EventTrigger 不支持附加事件.Caliburn micro 将它用于操作,因此我附加的事件不起作用.解决方案是编写自定义事件触发器并以显式方式使用 caliburn 微动作.自定义事件触发器取自该帖子:http://joyfulwpf.blogspot.com/2009/05/mvvm-invoking-command-on-attached-event.html?showComment=1323674885597#c8041424175408473805

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

然后当你想使用caliburn动作时:

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>

这篇关于使用带有 caliburn micro Message.Attach 的附加事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆