【问题标题】:MvvmCross bind to InteractionRequestMvvmCross 绑定到 InteractionRequest
【发布时间】:2013-10-11 15:03:05
【问题描述】:

我正在尝试在 iOS 中使用 mvvmcross 实现模式确认弹出窗口,遵循 this question 中的 Stuart 大纲。尝试将 InteractionRequest 绑定到事件处理程序时出现以下异常:

Problem seen during binding execution for to ConfirmationInteraction - problem
TargetInvocationException: Exception has been thrown by the target of an invocation.

内部异常是:

ArgumentNullException: missing source event info in MvxWeakEventSubscription
Parameter name: sourceEventInfo
at Cirrious.CrossCore.WeakSubscription.MvxWeakEventSubscription`2[System.Object,System.EventArgs]..ctor (System.Object source, System.Reflection.EventInfo sourceEventInfo, System.EventHandler`1 targetEventHandler) [0x00000] in <filename unknown>:0 
at Cirrious.CrossCore.WeakSubscription.MvxGeneralEventSubscription..ctor (System.Object source, System.Reflection.EventInfo eventInfo, System.EventHandler`1 eventHandler) [0x00000] in <filename unknown>:0 
at Cirrious.CrossCore.WeakSubscription.MvxWeakSubscriptionExtensionMethods.WeakSubscribe (System.Reflection.EventInfo eventInfo, System.Object source, System.EventHandler`1 eventHandler) [0x00000] in <filename unknown>:0 

大部分管道与上面提到的堆栈溢出问题相同,但为了完整起见,我将在此处发布:

public class InteractionRequestedEventArgs : EventArgs
{
    public Action Callback 
    { 
        get; 
        private set; 
    }

    public object Context 
    { 
        get; 
        private set; 
    }

    public InteractionRequestedEventArgs(object context, Action callback)
    {
        Context = context;
        Callback = callback;
    }
}

交互请求:

public class InteractionRequest<T> : IInteractionRequest
{
    public event EventHandler<InteractionRequestedEventArgs> Raised;

    public void Raise(T context, Action<T> callback)
    {
        var handler = this.Raised;
        if (handler != null)
        {
            handler(
                this, 
                new InteractionRequestedEventArgs(
                context, 
                () => callback(context)));
        }
    }
}

确认类:

public class Confirmation
{
    public string Message { get; private set; }
    public bool Confirmed { get; set; }
    public Confirmation(string message)
    {
        Message = message;
    }
}

在视图模型中,我们这样设置请求:

private InteractionRequest<Confirmation> _confirmCancelInteractionRequest = new InteractionRequest<Confirmation>();
    public IInteractionRequest ConfirmCancelInteractionRequest
    {
        get
        {
            return _confirmCancelInteractionRequest;
        }
    }

在视图中我们设置了事件订阅:

    private MvxGeneralEventSubscription _confirmationSubscription;
    private IInteractionRequest _confirmationInteraction;
    public IInteractionRequest ConfirmationInteraction
    {
        get { 
            return _confirmationInteraction; 
        }
        set
        {
            if (_confirmationInteraction == value)
                return;
            if (_confirmationSubscription != null)
                _confirmationSubscription.Dispose();
            _confirmationInteraction = value;
            if (_confirmationInteraction != null)
                _confirmationSubscription = _confirmationInteraction
                    .GetType ()
                    .GetEvent ("Raise")
                    .WeakSubscribe(_confirmationInteraction, DoConfirmation);

        }
    }

视图中的事件处理程序如下所示:

private void DoConfirmation(object s, EventArgs args)
    {
        var iArgs = (InteractionRequestedEventArgs)args;
        var confirmation = (Confirmation)iArgs.Context;

        var alert = new UIAlertView(); 
        alert.Title = "Bazinga"; 
        alert.Message = confirmation.Message; 

        alert.AddButton("Yes"); 
        alert.AddButton("No"); 

        alert.Clicked += (sender, e) => { 
            var alertView = sender as UIAlertView; 
                            // do something with the event
            iArgs.Callback();
        }; 
    }

最后是绑定,它位于视图的构造函数中。该视图是一个 MT 对话元素,因此是 DelayBind():

this.DelayBind(() =>
        {
            var set = this.CreateBindingSet<CustomerElement, CustomerViewModel>();
            ...
            set.Bind().For(my => my.ConfirmationInteraction).To(customer => customer.ConfirmCancelInteractionRequest);
            set.Apply();
        });
    }

【问题讨论】:

    标签: binding modal-dialog mvvmcross


    【解决方案1】:

    栈空引用异常

    at Cirrious.CrossCore.WeakSubscription.MvxWeakEventSubscription`2[System.Object,System.EventArgs]..ctor (System.Object source, System.Reflection.EventInfo sourceEventInfo, System.EventHandler`1 targetEventHandler) [0x00000] in <filename unknown>:0 
    at Cirrious.CrossCore.WeakSubscription.MvxGeneralEventSubscription..ctor (System.Object source, System.Reflection.EventInfo eventInfo, System.EventHandler`1 eventHandler) [0x00000] in <filename unknown>:0 
    at Cirrious.CrossCore.WeakSubscription.MvxWeakSubscriptionExtensionMethods.WeakSubscribe (System.Reflection.EventInfo eventInfo, System.Object source, System.EventHandler`1 eventHandler) [0x00000] in <filename unknown>:0 
    

    只有在_confirmationInteraction.GetType ().GetEvent ("Raise") 返回null 时才会发生

    所以...我认为问题可能在于您的活动被称为Raised


    如果有帮助:

    【讨论】:

    • 我也回过头来更正了原来的答案 - 希望这会帮助其他人(谢谢!)
    • 谢谢斯图尔特。我现在在绑定时遇到类型不匹配。
    • code 对象类型 System.EventHandler 无法转换为目标类型:System.EventHandler`1[[QuickAssessment.Core.Interaction.InteractionRequestedEventArgs, MyProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] 在 System.Reflection.Binder.ConvertValue(System.Object 值,System.Type 类型,System.Globalization.CultureInfo 文化,布尔精确匹配)[0x00027] 在 /Developer/MonoTouch/Source/mono/mcs/class /corlib/System.Reflection/Binder.cs:93
    • 对不起——回车键似乎想在我完成之前提交 cmets。它看起来像是类型不匹配,尽管 InterationRequestedEventArgs 确实继承自 System.EventArgs。无论如何,我会看看提到的其他一些解决方案,因为它们可能暂时符合要求。再次感谢。
    • 消息告诉您出了什么问题 - 在DoConfirmation(object s, EventArgs args)中使用类型化的 eventargs 参数
    猜你喜欢
    • 2013-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-18
    • 2013-10-17
    相关资源
    最近更新 更多