PageRenderTime 52ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/MVVMSidekick/MVVMSidekick.Shared/EventRouting.cs

https://github.com/zoujuny/MVVM-Sidekick
C# | 437 lines | 256 code | 93 blank | 88 comment | 20 complexity | 9443ef2c9b4aca22b6358be4f1107328 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.ComponentModel;
  6. using System.Linq.Expressions;
  7. using System.Runtime.Serialization;
  8. using System.Reflection;
  9. using System.Threading.Tasks;
  10. using System.Threading;
  11. using System.Windows.Input;
  12. using MVVMSidekick.ViewModels;
  13. using MVVMSidekick.Commands;
  14. using MVVMSidekick.Utilities;
  15. using System.Runtime.CompilerServices;
  16. using MVVMSidekick.Reactive;
  17. using System.Reactive.Linq;
  18. using System.Reactive.Subjects;
  19. using System.Reactive;
  20. using System.Collections.ObjectModel;
  21. using System.Collections.Specialized;
  22. using System.IO;
  23. using System.Collections;
  24. #if NETFX_CORE
  25. using Windows.UI.Xaml;
  26. using Windows.UI.Xaml.Data;
  27. using Windows.UI.Xaml.Controls;
  28. using System.Collections.Concurrent;
  29. using Windows.UI.Xaml.Navigation;
  30. using Windows.UI.Xaml.Controls.Primitives;
  31. #elif WPF
  32. using System.Windows;
  33. using System.Windows.Controls;
  34. using System.Windows.Data;
  35. using System.Collections.Concurrent;
  36. using System.Windows.Navigation;
  37. using MVVMSidekick.Views;
  38. using System.Windows.Controls.Primitives;
  39. #elif SILVERLIGHT_5||SILVERLIGHT_4
  40. using System.Windows;
  41. using System.Windows.Controls;
  42. using System.Windows.Data;
  43. using System.Windows.Navigation;
  44. using System.Windows.Controls.Primitives;
  45. #elif WINDOWS_PHONE_8||WINDOWS_PHONE_7
  46. using System.Windows;
  47. using System.Windows.Controls;
  48. using Microsoft.Phone.Controls;
  49. using System.Windows.Data;
  50. using System.Windows.Navigation;
  51. using System.Windows.Controls.Primitives;
  52. #endif
  53. namespace MVVMSidekick
  54. {
  55. namespace EventRouting
  56. {
  57. /// <summary>
  58. /// 全局事件根
  59. /// </summary>
  60. public class EventRouter
  61. {
  62. public EventRouter()
  63. {
  64. }
  65. static EventRouter()
  66. {
  67. Instance = new EventRouter();
  68. }
  69. public static EventRouter Instance { get; protected set; }
  70. /// <summary>
  71. /// 触发事件
  72. /// </summary>
  73. /// <typeparam name="TEventArgs">事件数据类型</typeparam>
  74. /// <param name="sender">事件发送者</param>
  75. /// <param name="eventArgs">事件数据</param>
  76. /// <param name="callerMemberNameOrEventName">发送事件名</param>
  77. public virtual void RaiseEvent<TEventArgs>(object sender, TEventArgs eventArgs, string callerMemberNameOrEventName = "")
  78. //#if !NETFX_CORE
  79. //// where TEventArgs : EventArgs
  80. //#endif
  81. {
  82. var eventObject = GetIEventObjectInstance(typeof(TEventArgs));
  83. eventObject.RaiseEvent(sender, callerMemberNameOrEventName, eventArgs);
  84. while (eventObject.BaseArgsTypeInstance != null)
  85. {
  86. eventObject = eventObject.BaseArgsTypeInstance;
  87. }
  88. }
  89. /// <summary>
  90. /// 触发事件
  91. /// </summary>
  92. /// <typeparam name="TEventArgs">事件数据类型</typeparam>
  93. /// <param name="sender">事件发送者</param>
  94. /// <param name="eventArgs">事件数据</param>
  95. /// <param name="callerMemberNameOrEventName">发送事件名</param>
  96. public virtual void RaiseEvent(object sender, object eventArgs, Type eventArgsType, string callerMemberNameOrEventName = "")
  97. //#if !NETFX_CORE
  98. //// where TEventArgs : EventArgs
  99. //#endif
  100. {
  101. var eventObject = GetIEventObjectInstance(eventArgsType);
  102. eventObject.RaiseEvent(sender, callerMemberNameOrEventName, eventArgs);
  103. while (eventObject.BaseArgsTypeInstance != null)
  104. {
  105. eventObject = eventObject.BaseArgsTypeInstance;
  106. }
  107. }
  108. /// <summary>
  109. /// 取得独立事件类
  110. /// </summary>
  111. /// <typeparam name="TEventArgs">事件数据类型</typeparam>
  112. /// <returns>事件独立类</returns>
  113. public virtual EventObject<TEventArgs> GetEventObject<TEventArgs>()
  114. #if !NETFX_CORE
  115. // where TEventArgs : EventArgs
  116. #endif
  117. {
  118. var eventObject = (EventObject<TEventArgs>)GetIEventObjectInstance(typeof(TEventArgs));
  119. return eventObject;
  120. }
  121. /// <summary>
  122. /// 事件来源的代理对象实例
  123. /// </summary>
  124. protected readonly ConcurrentDictionary<Type, IEventObject> EventObjects
  125. = new ConcurrentDictionary<Type, IEventObject>();
  126. /// <summary>
  127. /// 创建事件代理对象
  128. /// </summary>
  129. /// <param name="argsType">事件数据类型</param>
  130. /// <returns>代理对象实例</returns>
  131. protected IEventObject GetIEventObjectInstance(Type argsType)
  132. {
  133. var rval = EventObjects.GetOrAdd(
  134. argsType,
  135. t =>
  136. {
  137. try
  138. {
  139. var t2 = typeof(EventObject<>).MakeGenericType(t);
  140. return Activator.CreateInstance(t2) as IEventObject;
  141. }
  142. catch (Exception)
  143. {
  144. throw;
  145. }
  146. }
  147. );
  148. if (rval.BaseArgsTypeInstance == null)
  149. {
  150. #if NETFX_CORE
  151. var baseT = argsType.GetTypeInfo().BaseType;
  152. if (baseT != typeof(object) && baseT.Name != "RuntimeClass" && baseT != null )
  153. #else
  154. var baseT = argsType.BaseType;
  155. if (baseT != typeof(object) && baseT != null)
  156. #endif
  157. {
  158. rval.BaseArgsTypeInstance = GetIEventObjectInstance(baseT);
  159. }
  160. }
  161. return rval;
  162. }
  163. /// <summary>
  164. /// 事件对象接口
  165. /// </summary>
  166. public interface IEventObject
  167. {
  168. IEventObject BaseArgsTypeInstance { get; set; }
  169. void RaiseEvent(object sender, string eventName, object args);
  170. }
  171. /// <summary>
  172. ///事件对象
  173. /// </summary>
  174. /// <typeparam name="TEventArgs"></typeparam>
  175. public class EventObject<TEventArgs> : IEventObject, IObservable<RouterEventData<TEventArgs>>, IDisposable
  176. #if !NETFX_CORE
  177. // where TEventArgs : EventArgs
  178. #endif
  179. {
  180. private Subject<RouterEventData<TEventArgs>> _core = new Subject<RouterEventData<TEventArgs>>();
  181. public virtual IEventObject BaseArgsTypeInstance
  182. {
  183. get;
  184. set;
  185. }
  186. void IEventObject.RaiseEvent(object sender, string eventName, object args)
  187. {
  188. RaiseEvent(sender, eventName, (TEventArgs)args);
  189. }
  190. /// <summary>
  191. /// 发起事件
  192. /// </summary>
  193. /// <param name="sender">发送者</param>
  194. /// <param name="eventName">事件名</param>
  195. /// <param name="args">参数</param>
  196. public void RaiseEvent(object sender, string eventName, TEventArgs args)
  197. {
  198. var a = args;
  199. //if (a != null)
  200. //{
  201. // Event(sender, new DataEventArgs<RouterEventData<TEventArgs>>(new RouterEventData<TEventArgs>(sender, eventName, (TEventArgs)args)));
  202. _core.OnNext(new RouterEventData<TEventArgs>(sender, eventName, args));
  203. //}
  204. }
  205. //public event EventHandler<DataEventArgs<RouterEventData<TEventArgs>>> Event;
  206. public IDisposable Subscribe(IObserver<RouterEventData<TEventArgs>> observer)
  207. {
  208. return _core.Subscribe(observer);
  209. }
  210. int _Disposed = 0;
  211. ~EventObject()
  212. {
  213. Dispose(false);
  214. }
  215. public void Dispose()
  216. {
  217. Dispose(true);
  218. GC.SuppressFinalize(this);
  219. }
  220. virtual protected void Dispose(bool disposing)
  221. {
  222. var v = Interlocked.Exchange(ref _Disposed, 1);
  223. if (v == 0)
  224. {
  225. var cbak=Interlocked.Exchange(ref _core, null);
  226. if (cbak!=null)
  227. {
  228. try
  229. {
  230. cbak.Dispose();
  231. }
  232. catch (Exception)
  233. {
  234. }
  235. }
  236. if (disposing)
  237. {
  238. }
  239. }
  240. }
  241. }
  242. }
  243. /// <summary>
  244. /// 导航事件数据
  245. /// </summary>
  246. public class NavigateCommandEventArgs : EventArgs
  247. {
  248. public NavigateCommandEventArgs()
  249. {
  250. ParameterDictionary = new Dictionary<string, object>();
  251. }
  252. public NavigateCommandEventArgs(IDictionary<string, object> dic)
  253. : this()
  254. {
  255. foreach (var item in dic)
  256. {
  257. (ParameterDictionary as IDictionary<string, object>)[item.Key] = item.Value;
  258. }
  259. }
  260. public Dictionary<string, object> ParameterDictionary { get; set; }
  261. public Type SourceViewType { get; set; }
  262. public Type TargetViewType { get; set; }
  263. public IViewModel ViewModel { get; set; }
  264. public Object TargetFrame { get; set; }
  265. }
  266. /// <summary>
  267. /// 保存状态事件数据
  268. /// </summary>
  269. public class SaveStateEventArgs : EventArgs
  270. {
  271. public string ViewKeyId { get; set; }
  272. public Dictionary<string, object> State { get; set; }
  273. }
  274. /// <summary>
  275. /// 事件路由的扩展方法集合
  276. /// </summary>
  277. public static class EventRouterHelper
  278. {
  279. /// <summary>
  280. /// 触发事件
  281. /// </summary>
  282. /// <typeparam name="TEventArgs">事件类型</typeparam>
  283. /// <param name="source">事件来源</param>
  284. /// <param name="eventArgs">事件数据</param>
  285. /// <param name="callerMemberName">事件名</param>
  286. public static void RaiseEvent<TEventArgs>(this BindableBase source, TEventArgs eventArgs, string callerMemberName = "")
  287. #if !NETFX_CORE
  288. // where TEventArgs : EventArgs
  289. #endif
  290. {
  291. EventRouter.Instance.RaiseEvent(source, eventArgs, callerMemberName);
  292. }
  293. }
  294. /// <summary>
  295. /// 事件信息
  296. /// </summary>
  297. /// <typeparam name="TEventArgs">事件数据类型</typeparam>
  298. public struct RouterEventData<TEventArgs>
  299. #if ! NETFX_CORE
  300. //: EventArgs
  301. // where TEventArgs : EventArgs
  302. #endif
  303. {
  304. public RouterEventData(object sender, string eventName, TEventArgs eventArgs)
  305. {
  306. _Sender = sender;
  307. _EventName = eventName;
  308. _EventArgs = eventArgs;
  309. }
  310. private Object _Sender;
  311. /// <summary>
  312. /// 事件发送者
  313. /// </summary>
  314. public Object Sender
  315. {
  316. get { return _Sender; }
  317. }
  318. private string _EventName;
  319. /// <summary>
  320. /// 事件名
  321. /// </summary>
  322. public string EventName
  323. {
  324. get { return _EventName; }
  325. }
  326. private TEventArgs _EventArgs;
  327. /// <summary>
  328. /// 事件数据
  329. /// </summary>
  330. public TEventArgs EventArgs
  331. {
  332. get { return _EventArgs; }
  333. }
  334. }
  335. public class DataEventArgs<TData> : EventArgs
  336. {
  337. public DataEventArgs(TData data)
  338. {
  339. Data = data;
  340. }
  341. public TData Data { get; protected set; }
  342. }
  343. }
  344. }