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