WinRT:自己的事件处理程序,不会删除令牌

时间:2013-09-23 08:38:05

标签: c# events windows-runtime

我在WinRT中为自定义事件创建了一个类。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Text;
using System.Threading.Tasks;

namespace BA_Lib
{
    public class RTEventHandler<T>
    {
        private EventRegistrationTokenTable<EventHandler<T>> m_EventTokenTable = null;

        public event EventHandler<T> Event
        {
            add { EventRegistrationTokenTable<EventHandler<T>>.GetOrCreateEventRegistrationTokenTable(ref m_EventTokenTable).AddEventHandler(value); return; }
            remove { EventRegistrationTokenTable<EventHandler<T>>.GetOrCreateEventRegistrationTokenTable(ref m_EventTokenTable).RemoveEventHandler(value); }
        }

        public void Fire(T argument)
        {
            EventHandler<T> temp = EventRegistrationTokenTable<EventHandler<T>>.GetOrCreateEventRegistrationTokenTable(ref m_EventTokenTable).InvocationList;
            if (temp != null)
                temp(null, argument);
        }

        public void Fire(object sender,T argument)
        {
            EventHandler<T> temp = EventRegistrationTokenTable<EventHandler<T>>.GetOrCreateEventRegistrationTokenTable(ref m_EventTokenTable).InvocationList;
            if (temp != null)
                temp(sender, argument);
        }
    }
}

我使用此类为自己的事件创建自定义绑定,如下所示:

public RTEventHandler<int> Count{get;set;}

public void init(){Count=new RTEventHandler<int>();}

然后从其他课程开始:

EventHolder.Count.Event+=myEventHandler;

这就像魅力一样,但是当我尝试使用EventHolder.Count.Event-=myEventHandler;从事件中取消注册时,令牌保留就是表格。这会导致不必要的行为,因为事件处理程序会累积并多次触发。

1 个答案:

答案 0 :(得分:1)

我能够解决问题,并将发布我的最终解决方案以供进一步参考。

问题是,RemoveEventHandler函数需要一个令牌而不是处理程序。此令牌由AddEventHandler函数返回。因为添加返回无效,我无法将此令牌传回。我添加了一个字典来保存这个tokns并将它们链接到EventHandler。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Text;
using System.Threading.Tasks;

namespace BA_Lib
{
    public class RTEventHandler<T>
    {
        private EventRegistrationTokenTable<EventHandler<T>> m_EventTokenTable = null;
        Dictionary<EventHandler<T>, EventRegistrationToken> _tokens = new Dictionary<EventHandler<T>, EventRegistrationToken>();

        public event EventHandler<T> Event
        {
            add
            {
                if (_tokens.ContainsKey(value))
                    return;
                var token = EventRegistrationTokenTable<EventHandler<T>>.GetOrCreateEventRegistrationTokenTable(ref m_EventTokenTable).AddEventHandler(value);
                _tokens.Add(value, token);
                return;
            }
            remove
            {
                if (_tokens.ContainsKey(value))
                {
                    var token = _tokens[value];
                    EventRegistrationTokenTable<EventHandler<T>>.GetOrCreateEventRegistrationTokenTable(ref m_EventTokenTable).RemoveEventHandler(token);
                    _tokens.Remove(value);
                }
            }
        }

        public void Fire(T argument)
        {
            EventHandler<T> temp = EventRegistrationTokenTable<EventHandler<T>>.GetOrCreateEventRegistrationTokenTable(ref m_EventTokenTable).InvocationList;
            if (temp != null)
                temp(null, argument);
        }

        public void Fire(object sender, T argument)
        {
            EventHandler<T> temp = EventRegistrationTokenTable<EventHandler<T>>.GetOrCreateEventRegistrationTokenTable(ref m_EventTokenTable).InvocationList;
            if (temp != null)
                temp(sender, argument);
        }
    }
}

我正在做的是跟踪令牌和EventHanlder(要调用的函数)之间的连接。这样我就可以从函数中解析令牌并删除该条目。