MainViewModel.cs 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886
  1. using System;
  2. using System.Collections.Concurrent;
  3. using System.Collections.Generic;
  4. using System.Collections.ObjectModel;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Reflection;
  8. using System.Threading;
  9. using System.Threading.Tasks;
  10. using System.Windows;
  11. using System.Windows.Controls;
  12. using System.Windows.Input;
  13. using System.Windows.Threading;
  14. using Aitex.Core.Account;
  15. using Aitex.Core.Common.DeviceData;
  16. using Aitex.Core.RT.Event;
  17. using Aitex.Core.RT.Log;
  18. using Aitex.Core.Util;
  19. using Aitex.Core.WCF;
  20. using Caliburn.Micro;
  21. using MECF.Framework.Common.Account.Extends;
  22. using MECF.Framework.Common.DataCenter;
  23. using MECF.Framework.Common.Equipment;
  24. using MECF.Framework.Common.OperationCenter;
  25. using MECF.Framework.UI.Core.Accounts;
  26. using OpenSEMI.ClientBase;
  27. using OpenSEMI.ClientBase.Command;
  28. using OpenSEMI.ClientBase.Utility;
  29. using OpenSEMI.Core.Msg;
  30. using SciChart.Charting.ChartModifiers;
  31. using SciChart.Charting.Visuals;
  32. using SciChart.Charting.Visuals.Annotations;
  33. using SciChart.Charting.Visuals.Axes;
  34. using Virgo_DCommon;
  35. using Cali = Caliburn.Micro.Core;
  36. namespace Virgo_DUI.Client
  37. {
  38. public class TimeredMainViewModel : Cali.Conductor<Cali.Screen>.Collection.OneActive
  39. {
  40. private PeriodicJob _timer;
  41. private ConcurrentBag<string> _subscribedKeys = new ConcurrentBag<string>();
  42. public R_TRIG _rfAlarmTrigger = new R_TRIG();
  43. private Func<object, bool> _isSubscriptionAttribute;
  44. private Func<MemberInfo, bool> _hasSubscriptionAttribute;
  45. public string SoftwareVersion
  46. {
  47. get;
  48. set;
  49. }
  50. [Subscription("PMA.Rf.RfAlarm")]
  51. public bool RfAlarm
  52. {
  53. get;
  54. set;
  55. }
  56. [Subscription("PMA.IoMfc.MfcGas1.MfcAlarm")]
  57. public bool MfcAlarm1
  58. {
  59. get;
  60. set;
  61. }
  62. [Subscription("PMA.IoMfc.MfcGas2.MfcAlarm")]
  63. public bool MfcAlarm2
  64. {
  65. get;
  66. set;
  67. }
  68. [Subscription("PMA.IoMfc.MfcGas3.MfcAlarm")]
  69. public bool MfcAlarm3
  70. {
  71. get;
  72. set;
  73. }
  74. public string GetUnitStatusBackground(string status)
  75. {
  76. if (status == null) return "Black";
  77. status = status.Trim().ToLower();
  78. switch (status)
  79. {
  80. case "error":
  81. return "red";
  82. case "idle":
  83. return "Transparent";
  84. case "init":
  85. case "unknown":
  86. return "Yellow";
  87. default:
  88. return "LawnGreen";
  89. }
  90. }
  91. public TimeredMainViewModel()
  92. {
  93. _timer = new PeriodicJob(100, this.OnTimer, "UIUpdaterThread - " + GetType().Name);
  94. _isSubscriptionAttribute = attribute => attribute is SubscriptionAttribute;
  95. _hasSubscriptionAttribute = mi => mi.GetCustomAttributes(false).Any(_isSubscriptionAttribute);
  96. SoftwareVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
  97. NotifyOfPropertyChange("SoftwareVersion");
  98. SubscribeKeys(this);
  99. }
  100. //
  101. protected virtual bool OnTimer()
  102. {
  103. try
  104. {
  105. Poll();
  106. }
  107. catch (Exception ex)
  108. {
  109. LOG.Error(ex.Message);
  110. }
  111. return true;
  112. }
  113. public virtual void EnableTimer(bool enable)
  114. {
  115. if (enable) _timer.Start();
  116. else _timer.Pause();
  117. }
  118. protected virtual void Poll()
  119. {
  120. _rfAlarmTrigger.CLK = RfAlarm || MfcAlarm1 || MfcAlarm2 || MfcAlarm3;
  121. if (_rfAlarmTrigger.Q)
  122. InvokeClient.Instance.Service.DoOperation($"{ModuleName.PMA}.SignalTower.SwitchOnBuzzerAndRed");
  123. if (_subscribedKeys.Count > 0)
  124. {
  125. Dictionary<string, object> result = QueryDataClient.Instance.Service.PollData(_subscribedKeys);
  126. if (result == null)
  127. {
  128. LOG.Error("获取RT数据失败");
  129. return;
  130. }
  131. if (result.Count != _subscribedKeys.Count)
  132. {
  133. string unknowKeys = string.Empty;
  134. foreach (string key in _subscribedKeys)
  135. {
  136. if (!result.ContainsKey(key))
  137. {
  138. unknowKeys += key + "\r\n";
  139. }
  140. }
  141. //System.Diagnostics.Debug.Assert(false, unknowKeys);
  142. }
  143. InvokeBeforeUpdateProperty(result);
  144. UpdateValue(result);
  145. Application.Current.Dispatcher.Invoke(new System.Action(() =>
  146. {
  147. InvokePropertyChanged();
  148. InvokeAfterUpdateProperty(result);
  149. }));
  150. }
  151. }
  152. private void InvokePropertyChanged()
  153. {
  154. Refresh();
  155. }
  156. protected virtual void InvokeBeforeUpdateProperty(Dictionary<string, object> data)
  157. {
  158. }
  159. protected virtual void InvokeAfterUpdateProperty(Dictionary<string, object> data)
  160. {
  161. }
  162. void UpdateValue(Dictionary<string, object> data)
  163. {
  164. if (data == null)
  165. return;
  166. UpdateSubscribe(data, this);
  167. var properties = GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.GetCustomAttribute<SubscriptionModuleAttribute>() != null);
  168. foreach (var property in properties)
  169. {
  170. var moduleAttr = property.GetCustomAttribute<SubscriptionModuleAttribute>();
  171. UpdateSubscribe(data, property.GetValue(this), moduleAttr.Module);
  172. }
  173. }
  174. protected void Subscribe(string key)
  175. {
  176. if (!string.IsNullOrEmpty(key))
  177. {
  178. _subscribedKeys.Add(key);
  179. }
  180. }
  181. public void SubscribeKeys(TimeredMainViewModel target)
  182. {
  183. Parallel.ForEach(target.GetType().GetProperties().Where(_hasSubscriptionAttribute),
  184. property =>
  185. {
  186. SubscriptionAttribute subscription = property.GetCustomAttributes(false).First(_isSubscriptionAttribute) as SubscriptionAttribute;
  187. string key = subscription.ModuleKey;
  188. if (!_subscribedKeys.Contains(key))
  189. _subscribedKeys.Add(key);
  190. });
  191. Parallel.ForEach(target.GetType().GetFields().Where(_hasSubscriptionAttribute),
  192. method =>
  193. {
  194. SubscriptionAttribute subscription = method.GetCustomAttributes(false).First(_isSubscriptionAttribute) as SubscriptionAttribute;
  195. string key = subscription.ModuleKey;
  196. if (!_subscribedKeys.Contains(key))
  197. _subscribedKeys.Add(key);
  198. });
  199. }
  200. public void UpdateSubscribe(Dictionary<string, object> data, object target, string module = null)
  201. {
  202. Parallel.ForEach(target.GetType().GetProperties().Where(_hasSubscriptionAttribute),
  203. property =>
  204. {
  205. PropertyInfo pi = (PropertyInfo)property;
  206. SubscriptionAttribute subscription = property.GetCustomAttributes(false).First(_isSubscriptionAttribute) as SubscriptionAttribute;
  207. string key = subscription.ModuleKey;
  208. key = module == null ? key : string.Format("{0}.{1}", module, key);
  209. if (_subscribedKeys.Contains(key) && data.ContainsKey(key))
  210. {
  211. try
  212. {
  213. var convertedValue = Convert.ChangeType(data[key], pi.PropertyType);
  214. var originValue = Convert.ChangeType(pi.GetValue(target, null), pi.PropertyType);
  215. if (originValue != convertedValue)
  216. {
  217. if (pi.Name == "PumpLimitSetPoint")
  218. pi.SetValue(target, convertedValue, null);
  219. else
  220. pi.SetValue(target, convertedValue, null);
  221. }
  222. }
  223. catch (Exception ex)
  224. {
  225. LOG.Error("由RT返回的数据更新失败" + key, ex);
  226. }
  227. }
  228. });
  229. Parallel.ForEach(target.GetType().GetFields().Where(_hasSubscriptionAttribute),
  230. property =>
  231. {
  232. FieldInfo pi = (FieldInfo)property;
  233. SubscriptionAttribute subscription = property.GetCustomAttributes(false).First(_isSubscriptionAttribute) as SubscriptionAttribute;
  234. string key = subscription.ModuleKey;
  235. if (_subscribedKeys.Contains(key) && data.ContainsKey(key))
  236. {
  237. try
  238. {
  239. var convertedValue = Convert.ChangeType(data[key], pi.FieldType);
  240. pi.SetValue(target, convertedValue);
  241. }
  242. catch (Exception ex)
  243. {
  244. LOG.Error("由RT返回的数据更新失败" + key, ex);
  245. }
  246. }
  247. });
  248. }
  249. }
  250. public class MainViewModel : TimeredMainViewModel
  251. {
  252. public ObservableCollection<EventItem> WarnEventLogList { get; set; }
  253. public ObservableCollection<EventItem> EventLogList { get; set; }
  254. public Visibility AllEventsVisibility { get; set; }
  255. public Visibility WarnEventsVisibility { get; set; }
  256. [Subscription("Rt.Status")]
  257. public string RtStatus { get; set; }
  258. public string RtStatusBackground
  259. {
  260. get { return GetUnitStatusBackground(RtStatus); }
  261. }
  262. [Subscription("EFEM.FsmState")]
  263. public string EfemStatus { get; set; }
  264. public string EfemStatusBackground
  265. {
  266. get { return GetUnitStatusBackground(EfemStatus); }
  267. }
  268. [Subscription("FA.Status")]
  269. public string HostStatus { get; set; }
  270. public string HostStatusBackground
  271. {
  272. get { return GetUnitStatusBackground("Idle"); }
  273. }
  274. [Subscription("PMA.FsmState")]
  275. public string PMAStatus { get; set; }
  276. public string PMAStatusBackground
  277. {
  278. get { return GetUnitStatusBackground(PMAStatus); }
  279. }
  280. [Subscription("PMB.FsmState")]
  281. public string PMBStatus { get; set; }
  282. public string PMBStatusBackground
  283. {
  284. get { return GetUnitStatusBackground(PMBStatus); }
  285. }
  286. [Subscription("PMA.IsOnline")]
  287. public bool PMAIsOnline { get; set; }
  288. public string PMA_TopFrame_TextColor
  289. {
  290. get { return PMAIsOnline ? "LimeGreen" : "White"; }
  291. }
  292. [Subscription("PMB.IsOnline")]
  293. public bool PMBIsOnline { get; set; }
  294. public string PMB_TopFrame_TextColor
  295. {
  296. get { return PMBIsOnline ? "LimeGreen" : "White"; }
  297. }
  298. //[Subscription("EFEM.SignalTower")]
  299. [Subscription("PMA.SignalTower.DeviceData")]
  300. public AITSignalTowerData SignalTowerData
  301. {
  302. get;
  303. set;
  304. }
  305. private string _lastLoginName;
  306. public string LastLoginName
  307. {
  308. get { return _lastLoginName; }
  309. set
  310. {
  311. _lastLoginName = value;
  312. this.NotifyOfPropertyChange("LastLoginName");
  313. }
  314. }
  315. public MainViewModel()
  316. {
  317. BaseApp.Instance.Initialize();
  318. ((Virgo_DUI.Client.ClientApp)BaseApp.Instance).ViewModelSwitcher = this;
  319. this._models = new Dictionary<Type, BaseModel>();
  320. //for login part
  321. Roles = RoleAccountProvider.Instance.GetRoles();
  322. EventLogList = new ObservableCollection<EventItem>();
  323. EventClient.Instance.OnEvent += Instance_OnEvent;
  324. EventClient.Instance.OnDisconnectedWithRT += Instance_OnDisconnectedWithRT;
  325. EventClient.Instance.Start();
  326. WarnEventLogList = new ObservableCollection<EventItem>();
  327. SoftwareVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
  328. }
  329. private void Instance_OnDisconnectedWithRT()
  330. {
  331. MessageBox.Show("Disconnected with RT, UI will exit", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
  332. Environment.Exit(0);
  333. }
  334. public void ShowAlarmEvents()
  335. {
  336. AllEventsVisibility = Visibility.Hidden;
  337. WarnEventsVisibility = Visibility.Visible;
  338. this.NotifyOfPropertyChange("AllEventsVisibility");
  339. this.NotifyOfPropertyChange("WarnEventsVisibility");
  340. }
  341. public void ShowAllEvents()
  342. {
  343. AllEventsVisibility = Visibility.Visible;
  344. WarnEventsVisibility = Visibility.Hidden;
  345. this.NotifyOfPropertyChange("AllEventsVisibility");
  346. this.NotifyOfPropertyChange("WarnEventsVisibility");
  347. }
  348. private void Instance_OnEvent(EventItem obj)
  349. {
  350. switch (obj.Type)
  351. {
  352. case EventType.EventUI_Notify:
  353. LogEvent(obj);
  354. break;
  355. case EventType.Dialog_Nofity:
  356. //PopDialog(obj);
  357. break;
  358. case EventType.KickOut_Notify:
  359. break;
  360. case EventType.Sound_Notify:
  361. break;
  362. case EventType.UIMessage_Notify:
  363. //PopUIMessage(obj);
  364. break;
  365. }
  366. }
  367. void LogEvent(EventItem obj)
  368. {
  369. if (obj.Type != EventType.EventUI_Notify)
  370. return;
  371. Application.Current.Dispatcher.Invoke(() =>
  372. {
  373. while (EventLogList.Count > 100)
  374. {
  375. EventLogList.RemoveAt(0);
  376. }
  377. EventLogList.Add(obj);
  378. if (obj.Level == EventLevel.Alarm)
  379. this.WarnEventLogList.Add(obj);
  380. });
  381. }
  382. #region login part
  383. public void Enter(KeyEventArgs args, string loginName, PasswordBox password, Role role)
  384. {
  385. if (args.Key == Key.Enter)
  386. this.Login(loginName, password, role);
  387. }
  388. public void Login(string loginName, PasswordBox password, Role role)
  389. {
  390. try
  391. {
  392. LoginResult result = AccountClient.Instance.Service.LoginEx(loginName, password.Password, role.RoleID);
  393. if (result.ActSucc)
  394. {
  395. ClientApp.Instance.UserContext.LoginId = result.SessionId;
  396. ClientApp.Instance.UserMode = UserMode.Normal;
  397. ClientApp.Instance.UserContext.LoginName = loginName;
  398. ClientApp.Instance.UserContext.Role = role;
  399. ClientApp.Instance.UserContext.RoleID = role.RoleID;
  400. ClientApp.Instance.UserContext.RoleName = role.RoleName;
  401. ClientApp.Instance.UserContext.LoginTime = DateTime.Now;
  402. //ClientApp.Instance.UserContext.Token = token;
  403. ClientApp.Instance.UserContext.LastAccessTime = DateTime.Now;
  404. ClientApp.Instance.UserContext.IsLogin = true;
  405. //Load menu by role
  406. //filer menu if necessary...
  407. ClientApp.Instance.MenuManager.LoadMenu(RoleAccountProvider.Instance.GetMenusByRole(role.RoleID, ClientApp.Instance.MenuLoader.MenuList));
  408. InitMenu(); //bind menu to main view
  409. IsLogin = true; //control the display logic of main view
  410. //main view is common page, need register keys with true flag
  411. ClientApp.Instance.StatesManager.Register(new List<string>() { "System.RtStatus" }, true);
  412. LOG.Info(string.Format("{0} login as {1}", loginName, role.RoleName));
  413. }
  414. else
  415. {
  416. Enum.TryParse(result.Description, out AuthorizeResult errCode);
  417. switch (errCode)
  418. {
  419. case AuthorizeResult.None:
  420. DialogBox.ShowError("Not connected with RT.");
  421. break;
  422. case AuthorizeResult.WrongPwd:
  423. DialogBox.ShowError("Invalid password.");
  424. break;
  425. case AuthorizeResult.HasLogin:
  426. DialogBox.ShowError("{0} has already logged in.", loginName);
  427. break;
  428. case AuthorizeResult.NoMatchRole:
  429. DialogBox.ShowError("{0} does not match {1} role.", loginName, role.RoleName);
  430. break;
  431. case AuthorizeResult.NoMatchUser:
  432. DialogBox.ShowError("{0} does not exists.", loginName);
  433. break;
  434. case AuthorizeResult.NoSession:
  435. DialogBox.ShowError("The current session is invalid.");
  436. break;
  437. }
  438. }
  439. password.Clear();
  440. }
  441. catch (Exception ex)
  442. {
  443. LOG.Error(ex.Message, ex);
  444. }
  445. }
  446. #endregion login part
  447. public void Logout()
  448. {
  449. this.OnLogoutCommand();
  450. }
  451. public void OnLogoutCommand()
  452. {
  453. WindowManager windowmanager = new WindowManager();
  454. var logoffViewmodel = new LogoffViewModel();
  455. windowmanager.ShowDialog(logoffViewmodel);
  456. BaseApp.Instance.UserMode = logoffViewmodel.DialogResult;
  457. switch (logoffViewmodel.DialogResult)
  458. {
  459. case UserMode.Logoff:
  460. BaseApp.Instance.UserMode = UserMode.Logoff;
  461. if (BaseApp.Instance.UserContext.IsLogin)
  462. {
  463. try
  464. {
  465. AccountClient.Instance.Service.LogoutEx(BaseApp.Instance.UserContext.LoginName, BaseApp.Instance.UserContext.LoginId);
  466. BaseApp.Instance.UserContext.IsLogin = false;
  467. LOG.Info(string.Format("{0} logoff as {1}", BaseApp.Instance.UserContext.LoginName, BaseApp.Instance.UserContext.RoleName));
  468. }
  469. catch (Exception exp)
  470. {
  471. LOG.Write(exp);
  472. }
  473. }
  474. IsLogin = false; //no independent login page
  475. break;
  476. case UserMode.Exit:
  477. AccountClient.Instance.Service.LogoutEx(BaseApp.Instance.UserContext.LoginName, BaseApp.Instance.UserContext.LoginId);
  478. BaseApp.Instance.UserMode = UserMode.Exit;
  479. LOG.Info(string.Format("{0} exit as {1}", BaseApp.Instance.UserContext.LoginName, BaseApp.Instance.UserContext.RoleName));
  480. MsgPool.TerminateAll();
  481. this.TryClose();
  482. break;
  483. case UserMode.Shutdown:
  484. AccountClient.Instance.Service.LogoutEx(BaseApp.Instance.UserContext.LoginName, BaseApp.Instance.UserContext.LoginId);
  485. ShutdownWindow = new ShutdownViewModel();
  486. ShutdownThread = ShutdownExecute;
  487. windowmanager.ShowWindow(ShutdownWindow);
  488. ShutdownThread.BeginInvoke(ShutdownCallBack, ShutdownThread);
  489. break;
  490. }
  491. }
  492. public void Reset()
  493. {
  494. _rfAlarmTrigger.RST = true;
  495. InvokeClient.Instance.Service.DoOperation("System.Reset");
  496. }
  497. public void BuzzerOff()
  498. {
  499. //InvokeClient.Instance.Service.DoOperation($"{ModuleName.EFEM}.{EfemOperation.TurnOffAllLights}");
  500. InvokeClient.Instance.Service.DoOperation($"{ModuleName.PMA}.SignalTower.SwitchOffBuzzer");
  501. }
  502. #region override functions
  503. public override void CanClose(Action<bool> callback)
  504. {
  505. if (BaseApp.Instance.UserMode == UserMode.Normal)
  506. {
  507. callback(false);
  508. Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, (ThreadStart)delegate
  509. {
  510. this.OnLogoutCommand();
  511. });
  512. }
  513. else
  514. callback(true);
  515. }
  516. protected override void OnInitialize()
  517. {
  518. //display system version or other info...
  519. this.DisplayName = QueryDataClient.Instance.Service.GetConfig($"System.DisplayLogoName")?.ToString();
  520. base.OnInitialize();
  521. this.StartTimer();
  522. DrawSciChart();
  523. //TODO, Login
  524. //Login("admin", new PasswordBox() { Password = "admin" }, new Role("0", "Manager", false, 1000, ""));
  525. }
  526. protected override void OnActivate()
  527. {
  528. base.OnActivate();
  529. this.ShowAllEvents();
  530. EnableTimer(true);
  531. }
  532. void DrawSciChart()
  533. {
  534. // Create the chart surface
  535. var sciChartSurface = new SciChartSurface();
  536. // Create the X and Y Axis
  537. var xAxis = new NumericAxis() { AxisTitle = "Number of Samples (per series)" };
  538. var yAxis = new NumericAxis() { AxisTitle = "Value" };
  539. sciChartSurface.XAxis = xAxis;
  540. sciChartSurface.YAxis = yAxis;
  541. // Specify Interactivity Modifiers
  542. sciChartSurface.ChartModifier = new ModifierGroup(new RubberBandXyZoomModifier(), new ZoomExtentsModifier());
  543. // Add annotation hints to the user
  544. var textAnnotation = new TextAnnotation()
  545. {
  546. Text = "Hello World!",
  547. X1 = 5.0,
  548. Y1 = 5.0
  549. };
  550. sciChartSurface.Annotations.Add(textAnnotation);
  551. }
  552. protected override void OnViewLoaded(object view)
  553. {
  554. base.OnViewLoaded(view);
  555. this._view = view as MainView;
  556. this._view.tbLoginName.Focus();
  557. }
  558. protected override void OnDeactivate(bool close)
  559. {
  560. base.OnDeactivate(close);
  561. EnableTimer(false);
  562. }
  563. #endregion override functions
  564. #region
  565. #region Sync ShutDown Thread
  566. public delegate void ShutDownSysncThread();
  567. private ShutDownSysncThread ShutdownThread = null;
  568. private ShutdownViewModel ShutdownWindow = null;
  569. private void ShutdownExecute()
  570. {
  571. MsgPool.TerminateAll();
  572. BaseApp.Instance.UserMode = UserMode.Shutdown;
  573. BaseApp.Instance.UserContext.IsLogin = false;
  574. LOG.Info(string.Format("{0} shutdown as {1}", BaseApp.Instance.UserContext.LoginName, BaseApp.Instance.UserContext.RoleName));
  575. this.TryClose();
  576. }
  577. private void ShutdownCallBack(IAsyncResult result)
  578. {
  579. if (ShutdownWindow != null)
  580. {
  581. ShutdownWindow.TryClose();
  582. }
  583. ShutdownThread.EndInvoke(result);
  584. }
  585. #endregion Sync ShutDown Thread
  586. #region Menu Control and page switch
  587. private void InitMenu()
  588. {
  589. this.MenuItems = BaseApp.Instance.MenuManager.MenuItems;
  590. this.HistoryMenus = new ObservableCollection<AppMenu>();
  591. if (this.MenuItems.Count > 0)
  592. {
  593. foreach (AppMenu menuitem in this.MenuItems)
  594. {
  595. if (menuitem.MenuItems.Count > 0)
  596. {
  597. this.SwitchMenuItem(menuitem.MenuItems[0]);
  598. break;
  599. }
  600. }
  601. }
  602. }
  603. public void MainSwitchMenuItem(AppMenu menuViewItem)
  604. {
  605. if (menuViewItem.MenuItems.Count > 0)
  606. {
  607. if (menuViewItem.LastSelectedSubMenu != null)
  608. SwitchMenuItem(menuViewItem.LastSelectedSubMenu);
  609. else
  610. SwitchMenuItem(menuViewItem.MenuItems[0]);
  611. }
  612. }
  613. public void SwitchMenuItem(AppMenu menuViewItem)
  614. {
  615. if (menuViewItem.ViewModel != null && menuViewItem.ViewModel != string.Empty)
  616. {
  617. if (menuViewItem.Model == null)
  618. {
  619. menuViewItem.Model = (BaseModel)AssemblyUtil.CreateInstance(AssemblyUtil.GetType(menuViewItem.ViewModel));
  620. ((BaseModel)menuViewItem.Model).Permission = menuViewItem.Permission;
  621. ((BaseModel)menuViewItem.Model).Token = BaseApp.Instance.UserContext.Token;
  622. if (menuViewItem.Model is ISupportMultipleSystem)
  623. (menuViewItem.Model as ISupportMultipleSystem).SystemName = menuViewItem.System;
  624. }
  625. this.ActivateItem(((BaseModel)menuViewItem.Model));
  626. CurrentViewModel = ((BaseModel)menuViewItem.Model);
  627. if (((BaseModel)menuViewItem.Model).Page != PageID.MAX_PAGE)
  628. BaseApp.Instance.SetCurrentPage(((BaseModel)menuViewItem.Model).Page);
  629. this.HandleSubAndHistoryMenu(menuViewItem);
  630. if (this._currentMenuItem != null)
  631. {
  632. this._currentMenuItem.Selected = false;
  633. this._currentMenuItem.Parent.Selected = false;
  634. }
  635. menuViewItem.Selected = true;
  636. menuViewItem.Parent.Selected = true;
  637. menuViewItem.Parent.LastSelectedSubMenu = menuViewItem;
  638. this._currentMenuItem = menuViewItem;
  639. }
  640. }
  641. private void HandleSubAndHistoryMenu(AppMenu menuitem)
  642. {
  643. this.SubMenuItems = menuitem.Parent.MenuItems;
  644. if (!this.HistoryMenus.Contains(menuitem))
  645. {
  646. if (this.HistoryMenus.Count >= 8)
  647. this.HistoryMenus.RemoveAt(7);
  648. this.HistoryMenus.Insert(0, menuitem);
  649. }
  650. else
  651. {
  652. this.HistoryMenus.Remove(menuitem);
  653. this.HistoryMenus.Insert(0, menuitem);
  654. }
  655. }
  656. public bool SwitchPage(string firstLevelMenuID, string secondLevelMenuID)
  657. {
  658. foreach (AppMenu menuitem in BaseApp.Instance.MenuManager.MenuItems)
  659. {
  660. if (menuitem.MenuID == firstLevelMenuID)
  661. {
  662. foreach (AppMenu menu in menuitem.MenuItems)
  663. {
  664. if (menu.MenuID == secondLevelMenuID)
  665. {
  666. SwitchMenuItem(menu);
  667. return true;
  668. }
  669. }
  670. }
  671. }
  672. return false;
  673. }
  674. #endregion Menu Control and page switch
  675. #region Refresh Date Time on page
  676. private void StartTimer()
  677. {
  678. System.Windows.Threading.DispatcherTimer myDispatcherTimer =
  679. new System.Windows.Threading.DispatcherTimer();
  680. myDispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 1000);
  681. myDispatcherTimer.Tick += new EventHandler(Each_Tick);
  682. myDispatcherTimer.Start();
  683. }
  684. public void Each_Tick(object o, EventArgs sender)
  685. {
  686. this.NowDateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
  687. this.NotifyOfPropertyChange("NowDateTime");
  688. }
  689. #endregion Refresh Date Time on page
  690. #endregion
  691. public string NowDateTime { get; set; }
  692. private bool _IsLogin = false;
  693. public bool IsLogin
  694. {
  695. get { return _IsLogin; }
  696. set { _IsLogin = value; NotifyOfPropertyChange("IsLogin"); }
  697. }
  698. private List<Role> roles;
  699. public List<Role> Roles
  700. {
  701. get { return this.roles; }
  702. set { this.roles = value; this.RaisePropertyChangedEventImmediately("Roles"); }
  703. }
  704. private ICommand menuItemClickCommand;
  705. public ICommand MenuItemClickCommand
  706. {
  707. get
  708. {
  709. if (this.menuItemClickCommand == null)
  710. this.menuItemClickCommand = new BaseCommand<AppMenu>((AppMenu menuViewItem) => this.SwitchMenuItem(menuViewItem));
  711. return this.menuItemClickCommand;
  712. }
  713. }
  714. private ICommand mainmenuItemClickCommand;
  715. public ICommand MainMenuItemClickCommand
  716. {
  717. get
  718. {
  719. if (this.mainmenuItemClickCommand == null)
  720. this.mainmenuItemClickCommand = new BaseCommand<AppMenu>((AppMenu menuViewItem) => this.MainSwitchMenuItem(menuViewItem));
  721. return this.mainmenuItemClickCommand;
  722. }
  723. }
  724. public List<AppMenu> MenuItems
  725. {
  726. get { return this.menuItems; }
  727. set { this.menuItems = value; this.NotifyOfPropertyChange("MenuItems"); }
  728. }
  729. public List<AppMenu> SubMenuItems
  730. {
  731. get { return this.subMenuItems; }
  732. set { this.subMenuItems = value; this.NotifyOfPropertyChange("SubMenuItems"); }
  733. }
  734. public ObservableCollection<AppMenu> HistoryMenus
  735. {
  736. get { return this.historyItems; }
  737. set { this.historyItems = value; this.NotifyOfPropertyChange("HistoryMenus"); }
  738. }
  739. public string Context
  740. {
  741. get { return this.context; }
  742. set { this.context = value; this.NotifyOfPropertyChange("Context"); }
  743. }
  744. public BaseModel CurrentViewModel { get; private set; }
  745. public UserContext User { get { return BaseApp.Instance.UserContext; } }
  746. private AppMenu _currentMenuItem;
  747. private List<AppMenu> menuItems;
  748. private List<AppMenu> subMenuItems;
  749. private ObservableCollection<AppMenu> historyItems;
  750. private string context;
  751. private MainView _view;
  752. private Dictionary<Type, BaseModel> _models;
  753. }
  754. }