MainViewModel.cs 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371
  1. using Aitex.Core.Account;
  2. using Aitex.Core.Common.DeviceData;
  3. using Aitex.Core.RT.Event;
  4. using Aitex.Core.RT.Log;
  5. using Aitex.Core.UI.Dialog;
  6. using Aitex.Core.Util;
  7. using Aitex.Core.WCF;
  8. using Caliburn.Micro;
  9. using MECF.Framework.Common.Account.Extends;
  10. using MECF.Framework.Common.DataCenter;
  11. using MECF.Framework.Common.Equipment;
  12. using MECF.Framework.Common.OperationCenter;
  13. using MECF.Framework.UI.Core.Accounts;
  14. using OpenSEMI.ClientBase;
  15. using OpenSEMI.ClientBase.Command;
  16. using OpenSEMI.ClientBase.Utility;
  17. using OpenSEMI.Core.Msg;
  18. using SciChart.Charting.ChartModifiers;
  19. using SciChart.Charting.Visuals;
  20. using SciChart.Charting.Visuals.Annotations;
  21. using SciChart.Charting.Visuals.Axes;
  22. using SciChart.Core.Extensions;
  23. using System;
  24. using System.Collections.Concurrent;
  25. using System.Collections.Generic;
  26. using System.Collections.ObjectModel;
  27. using System.Data;
  28. using System.Linq;
  29. using System.Reflection;
  30. using System.Runtime.InteropServices;
  31. using System.Threading;
  32. using System.Threading.Tasks;
  33. using System.Windows;
  34. using System.Windows.Controls;
  35. using System.Windows.Input;
  36. using System.Windows.Threading;
  37. using VirgoCommon;
  38. using VirgoUI.Client.Models.History.Statistics;
  39. using VirgoUI.Client.Models.Operate.WaferAssociation;
  40. using VirgoUI.Client.Models.PMs;
  41. using VirgoUI.Client.Models.Sys;
  42. using Cali = Caliburn.Micro.Core;
  43. namespace VirgoUI.Client
  44. {
  45. public class TimeredMainViewModel : Cali.Conductor<Cali.Screen>.Collection.OneActive
  46. {
  47. private PeriodicJob _timer;
  48. public R_TRIG _trigGauge = new R_TRIG();
  49. public R_TRIG _trigAlarm = new R_TRIG();
  50. public R_TRIG _trigPMAStatsWarning = new R_TRIG();
  51. public R_TRIG _trigPMBStatsWarning = new R_TRIG();
  52. public R_TRIG _trigPMAStatsAlarm = new R_TRIG();
  53. public R_TRIG _trigPMBStatsAlarm = new R_TRIG();
  54. private ConcurrentBag<string> _subscribedKeys = new ConcurrentBag<string>();
  55. public ObservableCollection<StatsDataListItem> StatData { get; set; }
  56. private Func<object, bool> _isSubscriptionAttribute;
  57. private Func<MemberInfo, bool> _hasSubscriptionAttribute;
  58. public string SoftwareVersion
  59. {
  60. get;
  61. set;
  62. }
  63. public string SystemTime
  64. {
  65. get { return DateTime.Now.ToString("HH:mm:ss"); }
  66. }
  67. public string GetUnitStatusBackground(string status)
  68. {
  69. if (status == null) return "Black";
  70. status = status.Trim().ToLower();
  71. switch (status)
  72. {
  73. case "error":
  74. return "red";
  75. case "idle":
  76. return "Transparent";
  77. case "init":
  78. case "unknown":
  79. return "Yellow";
  80. default:
  81. return "LawnGreen";
  82. }
  83. }
  84. public TimeredMainViewModel()
  85. {
  86. _timer = new PeriodicJob(1000, this.OnTimer, "UIUpdaterThread - " + GetType().Name);
  87. StatData = new ObservableCollection<StatsDataListItem>();
  88. _isSubscriptionAttribute = attribute => attribute is SubscriptionAttribute;
  89. _hasSubscriptionAttribute = mi => mi.GetCustomAttributes(false).Any(_isSubscriptionAttribute);
  90. SoftwareVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
  91. NotifyOfPropertyChange("SoftwareVersion");
  92. SubscribeKeys(this);
  93. }
  94. //
  95. protected virtual bool OnTimer()
  96. {
  97. try
  98. {
  99. Poll();
  100. }
  101. catch (Exception ex)
  102. {
  103. LOG.Error(ex.Message);
  104. }
  105. return true;
  106. }
  107. public virtual void EnableTimer(bool enable)
  108. {
  109. if (enable) _timer.Start();
  110. else _timer.Pause();
  111. }
  112. protected virtual void Poll()
  113. {
  114. //此处在reset之后会报警
  115. //_trigGauge.CLK = PMARfAlarm || PMAMfcAlarm1 || PMAMfcAlarm2 || PMAMfcAlarm3 || PMAMfcAlarm4 || PMAMfcAlarm5
  116. // || PMBRfAlarm || PMBMfcAlarm1 || PMBMfcAlarm2 || PMBMfcAlarm3 || PMBMfcAlarm4 || PMBMfcAlarm5
  117. // || PMAMfcGas1PressureAlarm && PMAMfcGas2PressureAlarm && PMAMfcGas3PressureAlarm && PMAMfcGas4PressureAlarm && PMAMfcGas5PressureAlarm
  118. // || PMBMfcGas1PressureAlarm && PMBMfcGas2PressureAlarm && PMBMfcGas3PressureAlarm && PMBMfcGas4PressureAlarm && PMBMfcGas5PressureAlarm;
  119. //if (_trigGauge.Q)
  120. //{
  121. // InvokeClient.Instance.Service.DoOperation($"{ModuleName.EFEM}.{EfemOperation.SwitchOnBuzzerAndRed}");
  122. //}
  123. //_trigAlarm.CLK = PMAIsAlarm || PMBIsAlarm;
  124. //if (_trigAlarm.Q)
  125. //{
  126. // InvokeClient.Instance.Service.DoOperation($"{ModuleName.EFEM}.{EfemOperation.SwitchOnBuzzerAndRed}");
  127. //}
  128. if (_subscribedKeys.Count > 0)
  129. {
  130. Dictionary<string, object> result = QueryDataClient.Instance.Service.PollData(_subscribedKeys);
  131. if (result == null)
  132. {
  133. LOG.Error("Failed to obtain RT data");
  134. return;
  135. }
  136. if (result.Count != _subscribedKeys.Count)
  137. {
  138. string unknowKeys = string.Empty;
  139. foreach (string key in _subscribedKeys)
  140. {
  141. if (!result.ContainsKey(key))
  142. {
  143. unknowKeys += key + "\r\n";
  144. }
  145. }
  146. //System.Diagnostics.Debug.Assert(false, unknowKeys);
  147. }
  148. InvokeBeforeUpdateProperty(result);
  149. UpdateValue(result);
  150. Application.Current.Dispatcher.Invoke(new System.Action(() =>
  151. {
  152. InvokePropertyChanged();
  153. InvokeAfterUpdateProperty(result);
  154. }));
  155. }
  156. string sql = $"SELECT * FROM \"stats_data\" order by \"name\" ASC;";
  157. DataTable dbData = QueryDataClient.Instance.Service.QueryData(sql);
  158. if (dbData == null || dbData.Rows.Count == 0)
  159. return;
  160. string[] clearedNameList = Array.ConvertAll<StatsDataListItem, string>(StatData.ToArray(), x => x.Name);
  161. List<string> removableList = new List<string>();
  162. if (clearedNameList.Length > 0)
  163. removableList = clearedNameList.ToList();
  164. for (int i = 0; i < dbData.Rows.Count; i++)
  165. {
  166. if (!dbData.Rows[i]["is_visible"].Equals(DBNull.Value) && !Convert.ToBoolean(dbData.Rows[i]["is_visible"].ToString()))
  167. continue;
  168. string name = dbData.Rows[i]["name"].ToString();
  169. removableList.RemoveIfContains(name);
  170. StatsDataListItem item = StatData.FirstOrDefault(x => x.Name == name);
  171. if (item == null)
  172. {
  173. item = new StatsDataListItem();
  174. item.Name = dbData.Rows[i]["name"].ToString();
  175. item.AlarmEnable = false;
  176. item.WarningEnable = false;
  177. item.IsVisible = true;
  178. item.AlarmTextSaved = true;
  179. item.WarningTextSaved = true;
  180. item.AlarmValueSetPoint = dbData.Rows[i]["alarm_value"].ToString();
  181. item.WarningValueSetPoint = dbData.Rows[i]["warning_value"].ToString();
  182. StatData.Add(item);
  183. }
  184. item.Description = dbData.Rows[i]["description"].ToString();
  185. item.Value = dbData.Rows[i]["value"].ToString();
  186. item.Total = dbData.Rows[i]["total"].ToString();
  187. if (!dbData.Rows[i]["enable_warning"].Equals(DBNull.Value))
  188. item.WarningEnable = Convert.ToBoolean(dbData.Rows[i]["enable_warning"].ToString());
  189. item.WarningValue = dbData.Rows[i]["warning_value"].ToString();
  190. if (!dbData.Rows[i]["enable_alarm"].Equals(DBNull.Value))
  191. item.AlarmEnable = Convert.ToBoolean(dbData.Rows[i]["enable_alarm"].ToString());
  192. item.AlarmValue = dbData.Rows[i]["alarm_value"].ToString();
  193. }
  194. foreach (var name in removableList)
  195. {
  196. StatsDataListItem item = StatData.FirstOrDefault(x => x.Name == name);
  197. if (item != null)
  198. StatData.Remove(item);
  199. }
  200. foreach (var item in StatData)
  201. {
  202. if (item.Name == "PMA.ProcessedWaferCount")
  203. {
  204. _trigPMAStatsAlarm.CLK = item.AlarmEnable && Convert.ToInt32(item.AlarmValue) < Convert.ToInt32(item.Value);
  205. if (_trigPMAStatsAlarm.Q)
  206. {
  207. InvokeClient.Instance.Service.DoOperation("System.Stats.Alarm", item.Name);
  208. }
  209. _trigPMAStatsWarning.CLK = item.WarningEnable && Convert.ToInt32(item.WarningValue) < Convert.ToInt32(item.Value);
  210. if (_trigPMAStatsWarning.Q)
  211. {
  212. InvokeClient.Instance.Service.DoOperation("System.Stats.Warning", item.Name);
  213. }
  214. }
  215. if (item.Name == "PMB.ProcessedWaferCount")
  216. {
  217. _trigPMBStatsAlarm.CLK = item.AlarmEnable && Convert.ToInt32(item.AlarmValue) < Convert.ToInt32(item.Value);
  218. if (_trigPMBStatsAlarm.Q)
  219. {
  220. InvokeClient.Instance.Service.DoOperation("System.Stats.Alarm", item.Name);
  221. }
  222. _trigPMBStatsWarning.CLK = item.WarningEnable && Convert.ToInt32(item.WarningValue) < Convert.ToInt32(item.Value);
  223. if (_trigPMBStatsWarning.Q)
  224. {
  225. InvokeClient.Instance.Service.DoOperation("System.Stats.Warning", item.Name);
  226. }
  227. }
  228. }
  229. }
  230. private void InvokePropertyChanged()
  231. {
  232. Refresh();
  233. }
  234. protected virtual void InvokeBeforeUpdateProperty(Dictionary<string, object> data)
  235. {
  236. }
  237. protected virtual void InvokeAfterUpdateProperty(Dictionary<string, object> data)
  238. {
  239. }
  240. void UpdateValue(Dictionary<string, object> data)
  241. {
  242. if (data == null)
  243. return;
  244. UpdateSubscribe(data, this);
  245. var properties = GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.GetCustomAttribute<SubscriptionModuleAttribute>() != null);
  246. foreach (var property in properties)
  247. {
  248. var moduleAttr = property.GetCustomAttribute<SubscriptionModuleAttribute>();
  249. UpdateSubscribe(data, property.GetValue(this), moduleAttr.Module);
  250. }
  251. }
  252. protected void Subscribe(string key)
  253. {
  254. if (!string.IsNullOrEmpty(key))
  255. {
  256. _subscribedKeys.Add(key);
  257. }
  258. }
  259. public void SubscribeKeys(TimeredMainViewModel target)
  260. {
  261. Parallel.ForEach(target.GetType().GetProperties().Where(_hasSubscriptionAttribute),
  262. property =>
  263. {
  264. SubscriptionAttribute subscription = property.GetCustomAttributes(false).First(_isSubscriptionAttribute) as SubscriptionAttribute;
  265. string key = subscription.ModuleKey;
  266. if (!_subscribedKeys.Contains(key))
  267. _subscribedKeys.Add(key);
  268. });
  269. Parallel.ForEach(target.GetType().GetFields().Where(_hasSubscriptionAttribute),
  270. method =>
  271. {
  272. SubscriptionAttribute subscription = method.GetCustomAttributes(false).First(_isSubscriptionAttribute) as SubscriptionAttribute;
  273. string key = subscription.ModuleKey;
  274. if (!_subscribedKeys.Contains(key))
  275. _subscribedKeys.Add(key);
  276. });
  277. }
  278. public void UpdateSubscribe(Dictionary<string, object> data, object target, string module = null)
  279. {
  280. Parallel.ForEach(target.GetType().GetProperties().Where(_hasSubscriptionAttribute),
  281. property =>
  282. {
  283. PropertyInfo pi = (PropertyInfo)property;
  284. SubscriptionAttribute subscription = property.GetCustomAttributes(false).First(_isSubscriptionAttribute) as SubscriptionAttribute;
  285. string key = subscription.ModuleKey;
  286. key = module == null ? key : string.Format("{0}.{1}", module, key);
  287. if (_subscribedKeys.Contains(key) && data.ContainsKey(key))
  288. {
  289. try
  290. {
  291. var convertedValue = Convert.ChangeType(data[key], pi.PropertyType);
  292. var originValue = Convert.ChangeType(pi.GetValue(target, null), pi.PropertyType);
  293. if (originValue != convertedValue)
  294. {
  295. if (pi.Name == "PumpLimitSetPoint")
  296. pi.SetValue(target, convertedValue, null);
  297. else
  298. pi.SetValue(target, convertedValue, null);
  299. }
  300. }
  301. catch (Exception ex)
  302. {
  303. LOG.Error("Failed to update data returned by RT" + key, ex);
  304. }
  305. }
  306. });
  307. Parallel.ForEach(target.GetType().GetFields().Where(_hasSubscriptionAttribute),
  308. property =>
  309. {
  310. FieldInfo pi = (FieldInfo)property;
  311. SubscriptionAttribute subscription = property.GetCustomAttributes(false).First(_isSubscriptionAttribute) as SubscriptionAttribute;
  312. string key = subscription.ModuleKey;
  313. if (_subscribedKeys.Contains(key) && data.ContainsKey(key))
  314. {
  315. try
  316. {
  317. var convertedValue = Convert.ChangeType(data[key], pi.FieldType);
  318. pi.SetValue(target, convertedValue);
  319. }
  320. catch (Exception ex)
  321. {
  322. LOG.Error("Failed to update data returned by RT" + key, ex);
  323. }
  324. }
  325. });
  326. }
  327. }
  328. public class MainViewModel : TimeredMainViewModel
  329. {
  330. public bool IsAutoLogout { get; set; }
  331. public int LogoutTime { get; set; }
  332. public ObservableCollection<EventItem> WarnEventLogList { get; set; }
  333. public ObservableCollection<EventItem> EventLogList { get; set; }
  334. public Visibility AllEventsVisibility { get; set; }
  335. public Visibility WarnEventsVisibility { get; set; }
  336. public bool IsAlarmListOpen { get; set; }
  337. [Subscription("Rt.Status")]
  338. public string RtStatus { get; set; }
  339. public string RtStatusBackground
  340. {
  341. get { return GetUnitStatusBackground(RtStatus); }
  342. }
  343. [Subscription("EFEM.FsmState")]
  344. public string EfemStatus { get; set; }
  345. public string EfemStatusBackground
  346. {
  347. get { return GetUnitStatusBackground(EfemStatus); }
  348. }
  349. public string HostStatusBackground
  350. {
  351. get { return $"{HostCommunicationStatus}"; }
  352. }
  353. [Subscription("System.ControlStatus")]
  354. public string HostControlStatus
  355. {
  356. get;
  357. set;
  358. }
  359. public string HostControlStatusBackground
  360. {
  361. get
  362. {
  363. switch (HostControlStatus)
  364. {
  365. case "Unknown":
  366. return "Yellow";
  367. case "EquipmentOffline":
  368. case "AttemptOnline":
  369. case "HostOffline":
  370. return "Transparent";
  371. case "OnlineLocal":
  372. case "OnlineRemote":
  373. return "LawnGreen";
  374. default:
  375. return "Yellow";
  376. }
  377. }
  378. }
  379. [Subscription("System.CommunicationStatus")]
  380. public string HostCommunicationStatus
  381. {
  382. get;
  383. set;
  384. }
  385. /// Disabled = 0,
  386. /// Enabled = 1,
  387. /// EnabledNotCommunicating = 2,
  388. /// EnabledCommunicating = 3,
  389. /// WaitCRA = 4,
  390. /// WaitDelay = 5,
  391. /// WaitCRFromHost = 6,
  392. public string HostCommunicationStatusBackground
  393. {
  394. get
  395. {
  396. switch (HostCommunicationStatus)
  397. {
  398. case "Disabled":
  399. return "Yellow";
  400. case "Enabled":
  401. case "EnabledNotCommunicating":
  402. case "WaitCRA":
  403. case "WaitDelay":
  404. case "WaitCRFromHost":
  405. return "Transparent";
  406. case "EnabledCommunicating":
  407. return "LawnGreen";
  408. default:
  409. return "Yellow";
  410. }
  411. }
  412. }
  413. public bool IsEnableFAEnable
  414. {
  415. get
  416. {
  417. return HostCommunicationStatus == "Disabled";
  418. }
  419. }
  420. public bool IsDisableFAEnable
  421. {
  422. get
  423. {
  424. return HostCommunicationStatus != "Disabled";
  425. }
  426. }
  427. [Subscription("PMA.FsmState")]
  428. public string PMAStatus { get; set; }
  429. public string PMAStatusBackground
  430. {
  431. get { return GetUnitStatusBackground(PMAStatus); }
  432. }
  433. [Subscription("PMB.FsmState")]
  434. public string PMBStatus { get; set; }
  435. public string PMBStatusBackground
  436. {
  437. get { return GetUnitStatusBackground(PMBStatus); }
  438. }
  439. [Subscription("LP1.CassettePresent")]
  440. public int LP1Present { get; set; }
  441. [Subscription("LP2.CassettePresent")]
  442. public int LP2Present { get; set; }
  443. [Subscription("PMA.IsOnline")]
  444. public bool PMAIsOnline { get; set; }
  445. public string PMA_TopFrame_TextColor
  446. {
  447. get { return PMAIsOnline ? "LimeGreen" : "White"; }
  448. }
  449. [Subscription("PMB.IsOnline")]
  450. public bool PMBIsOnline { get; set; }
  451. public string PMB_TopFrame_TextColor
  452. {
  453. get { return PMBIsOnline ? "LimeGreen" : "White"; }
  454. }
  455. [Subscription("System.SignalTower.DeviceData")]
  456. public AITSignalTowerData SignalTowerData
  457. {
  458. get;
  459. set;
  460. }
  461. private string _lastLoginName;
  462. public string LastLoginName
  463. {
  464. get { return _lastLoginName; }
  465. set
  466. {
  467. _lastLoginName = value;
  468. this.NotifyOfPropertyChange("LastLoginName");
  469. }
  470. }
  471. private string _loginName;
  472. public string LoginName
  473. {
  474. get { return _loginName; }
  475. set
  476. {
  477. _loginName = value;
  478. this.NotifyOfPropertyChange("LoginName");
  479. }
  480. }
  481. private string _roleName;
  482. public string RoleName
  483. {
  484. get { return _roleName; }
  485. set
  486. {
  487. _roleName = value;
  488. this.NotifyOfPropertyChange("RoleName");
  489. }
  490. }
  491. [StructLayout(LayoutKind.Sequential)]
  492. internal struct LASTINPUTINFO
  493. {
  494. [MarshalAs(UnmanagedType.U4)]
  495. public int cbSize;
  496. [MarshalAs(UnmanagedType.U4)]
  497. public int dwTime;
  498. }
  499. [DllImport("user32.dll")]
  500. internal static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
  501. /// <summary>
  502. /// 获取鼠标键盘不活动的时间
  503. /// </summary>
  504. /// <returns>结果</returns>
  505. public static int GetLastInputTime()
  506. {
  507. LASTINPUTINFO lastInputInfo = new LASTINPUTINFO();
  508. lastInputInfo.cbSize = Marshal.SizeOf(lastInputInfo);
  509. lastInputInfo.dwTime = 0;
  510. int idleTime = 0;
  511. if (GetLastInputInfo(ref lastInputInfo))
  512. {
  513. idleTime = Environment.TickCount - lastInputInfo.dwTime;
  514. }
  515. return ((idleTime > 0) ? (idleTime / 1000) : 0);
  516. }
  517. public MainViewModel()
  518. {
  519. BaseApp.Instance.Initialize();
  520. ((VirgoUI.Client.ClientApp)BaseApp.Instance).ViewModelSwitcher = this;
  521. this._models = new Dictionary<Type, BaseModel>();
  522. //for login part
  523. Roles = RoleAccountProvider.Instance.GetRoles();
  524. EventLogList = new ObservableCollection<EventItem>();
  525. EventClient.Instance.OnEvent += Instance_OnEvent;
  526. EventClient.Instance.OnDisconnectedWithRT += Instance_OnDisconnectedWithRT;
  527. EventClient.Instance.Start();
  528. WarnEventLogList = new ObservableCollection<EventItem>();
  529. SoftwareVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
  530. }
  531. private void Instance_OnDisconnectedWithRT()
  532. {
  533. MessageBox.Show("Disconnected with RT, UI will exit", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
  534. Environment.Exit(0);
  535. }
  536. public void ShowAlarmEvents()
  537. {
  538. AllEventsVisibility = Visibility.Hidden;
  539. WarnEventsVisibility = Visibility.Visible;
  540. this.NotifyOfPropertyChange("AllEventsVisibility");
  541. this.NotifyOfPropertyChange("WarnEventsVisibility");
  542. }
  543. public void ShowAllEvents()
  544. {
  545. AllEventsVisibility = Visibility.Visible;
  546. WarnEventsVisibility = Visibility.Hidden;
  547. this.NotifyOfPropertyChange("AllEventsVisibility");
  548. this.NotifyOfPropertyChange("WarnEventsVisibility");
  549. }
  550. private void Instance_OnEvent(EventItem obj)
  551. {
  552. switch (obj.Type)
  553. {
  554. case EventType.EventUI_Notify:
  555. LogEvent(obj);
  556. break;
  557. case EventType.Dialog_Nofity:
  558. PopDialog(obj);
  559. break;
  560. case EventType.KickOut_Notify:
  561. break;
  562. case EventType.Sound_Notify:
  563. break;
  564. case EventType.UIMessage_Notify:
  565. //PopUIMessage(obj);
  566. break;
  567. }
  568. }
  569. void PopDialog(EventItem item)
  570. {
  571. Application.Current.Dispatcher.Invoke(new System.Action(() =>
  572. {
  573. switch (item.Level)
  574. {
  575. case EventLevel.Alarm:
  576. MessageBoxEx.ShowError(item.Description, item.Explaination);
  577. break;
  578. case EventLevel.Warning:
  579. MessageBoxEx.ShowWarning(item.Description, item.Explaination);
  580. break;
  581. case EventLevel.Information:
  582. MessageBoxEx.ShowInfo(item.Description, item.Explaination);
  583. break;
  584. case EventLevel.InformationNoDelay:
  585. ShowLotComplete(item.Explaination);
  586. //MessageBoxEx.ShowInfoNoDelay(item.Description, item.Explaination);
  587. break;
  588. }
  589. }));
  590. }
  591. LotCompleteDialogViewModel _lotCompleteDialog = new LotCompleteDialogViewModel();
  592. void ShowLotComplete(string result)
  593. {
  594. string[] info = result.Split(';');
  595. if (info.Length > 5)
  596. {
  597. var module = info[0];
  598. _lotCompleteDialog.DisplayName = "Information";
  599. //LP;WaferSize;Lot;Number;Start;End;
  600. if (module == "LP1")
  601. {
  602. _lotCompleteDialog.LP1LotComplete.Module = "LP1";
  603. _lotCompleteDialog.LP1LotComplete.LotID = info[2];
  604. _lotCompleteDialog.LP1LotComplete.WaferNumber = info[3];
  605. _lotCompleteDialog.LP1LotComplete.StartTime = info[4];
  606. _lotCompleteDialog.LP1LotComplete.EndTime = info[5];
  607. switch (info[1])
  608. {
  609. case "WS3":
  610. _lotCompleteDialog.LP1LotComplete.WaferSize = $"WS{QueryDataClient.Instance.Service.GetConfig($"System.SmallWafer")}";
  611. break;
  612. case "WS4":
  613. _lotCompleteDialog.LP1LotComplete.WaferSize = $"WS{QueryDataClient.Instance.Service.GetConfig($"System.MidWafer")}";
  614. break;
  615. case "WS6":
  616. _lotCompleteDialog.LP1LotComplete.WaferSize = $"WS{QueryDataClient.Instance.Service.GetConfig($"System.BigWafer")}";
  617. break;
  618. }
  619. _lotCompleteDialog.LP1LotComplete.InvokePropertyChanged();
  620. }
  621. if (module == "LP2")
  622. {
  623. _lotCompleteDialog.LP2LotComplete.Module = "LP2";
  624. _lotCompleteDialog.LP2LotComplete.LotID = info[2];
  625. _lotCompleteDialog.LP2LotComplete.WaferNumber = info[3];
  626. _lotCompleteDialog.LP2LotComplete.StartTime = info[4];
  627. _lotCompleteDialog.LP2LotComplete.EndTime = info[5];
  628. switch (info[1])
  629. {
  630. case "WS3":
  631. _lotCompleteDialog.LP2LotComplete.WaferSize = $"WS{QueryDataClient.Instance.Service.GetConfig($"System.SmallWafer")}";
  632. break;
  633. case "WS4":
  634. _lotCompleteDialog.LP2LotComplete.WaferSize = $"WS{QueryDataClient.Instance.Service.GetConfig($"System.MidWafer")}";
  635. break;
  636. case "WS6":
  637. _lotCompleteDialog.LP2LotComplete.WaferSize = $"WS{QueryDataClient.Instance.Service.GetConfig($"System.BigWafer")}";
  638. break;
  639. }
  640. _lotCompleteDialog.LP2LotComplete.InvokePropertyChanged();
  641. }
  642. _lotCompleteDialog.SetVisible(module, true);
  643. }
  644. if (!_lotCompleteDialog.IsDisplayed)
  645. {
  646. _lotCompleteDialog.IsDisplayed = true;
  647. Task.Run(() =>
  648. {
  649. Application.Current.Dispatcher.Invoke(() =>
  650. {
  651. WindowManager wm = new WindowManager();
  652. bool? bret = wm.ShowDialog(_lotCompleteDialog);
  653. if ((bool)bret)
  654. {
  655. }
  656. _lotCompleteDialog.IsDisplayed = false;
  657. });
  658. });
  659. }
  660. }
  661. void LogEvent(EventItem obj)
  662. {
  663. if (obj.Type != EventType.EventUI_Notify)
  664. return;
  665. Application.Current.Dispatcher.Invoke(() =>
  666. {
  667. while (EventLogList.Count > 100)
  668. {
  669. EventLogList.RemoveAt(0);
  670. }
  671. EventLogList.Add(obj);
  672. if (obj.Level == EventLevel.Alarm)
  673. this.WarnEventLogList.Add(obj);
  674. });
  675. if (this.WarnEventLogList.Count() > 1)
  676. this.IsAlarmListOpen = true;
  677. }
  678. void ResetAlarmList()
  679. {
  680. this.WarnEventLogList.Clear();
  681. }
  682. #region login part
  683. public void Enter(KeyEventArgs args, string loginName, PasswordBox password, Role role)
  684. {
  685. if (args.Key == Key.Enter)
  686. this.Login(loginName, password, role);
  687. }
  688. public void Login(string loginName, PasswordBox password, Role role)
  689. {
  690. try
  691. {
  692. LoginResult result = AccountClient.Instance.Service.LoginEx(loginName, password.Password, role.RoleID);
  693. if (result.ActSucc)
  694. {
  695. ClientApp.Instance.UserContext.LoginId = result.SessionId;
  696. ClientApp.Instance.UserMode = UserMode.Normal;
  697. ClientApp.Instance.UserContext.LoginName = loginName;
  698. ClientApp.Instance.UserContext.Role = role;
  699. ClientApp.Instance.UserContext.RoleID = role.RoleID;
  700. ClientApp.Instance.UserContext.RoleName = role.RoleName;
  701. ClientApp.Instance.UserContext.LoginTime = DateTime.Now;
  702. //ClientApp.Instance.UserContext.Token = token;
  703. ClientApp.Instance.UserContext.LastAccessTime = DateTime.Now;
  704. ClientApp.Instance.UserContext.IsLogin = true;
  705. //Load menu by role
  706. //filer menu if necessary...
  707. ClientApp.Instance.MenuManager.LoadMenu(RoleAccountProvider.Instance.GetMenusByRole(role.RoleID, ClientApp.Instance.MenuLoader.MenuList));
  708. IsAutoLogout = role.IsAutoLogout;
  709. LogoutTime = role.LogoutTime;
  710. InitMenu(); //bind menu to main view
  711. IsLogin = true; //control the display logic of main view
  712. //main view is common page, need register keys with true flag
  713. ClientApp.Instance.StatesManager.Register(new List<string>() { "System.RtStatus" }, true);
  714. LoginName = loginName;
  715. RoleName = role.RoleName;
  716. LOG.Info(string.Format("{0} login as {1}", loginName, role.RoleName));
  717. }
  718. else
  719. {
  720. Enum.TryParse(result.Description, out AuthorizeResult errCode);
  721. switch (errCode)
  722. {
  723. case AuthorizeResult.None:
  724. DialogBox.ShowError("Not connected with RT.");
  725. break;
  726. case AuthorizeResult.WrongPwd:
  727. DialogBox.ShowError("Invalid password.");
  728. break;
  729. case AuthorizeResult.HasLogin:
  730. DialogBox.ShowError("{0} has already logged in.", loginName);
  731. break;
  732. case AuthorizeResult.NoMatchRole:
  733. DialogBox.ShowError("{0} does not match {1} role.", loginName, role.RoleName);
  734. break;
  735. case AuthorizeResult.NoMatchUser:
  736. DialogBox.ShowError("{0} does not exists.", loginName);
  737. break;
  738. case AuthorizeResult.NoSession:
  739. DialogBox.ShowError("The current session is invalid.");
  740. break;
  741. }
  742. }
  743. password.Clear();
  744. }
  745. catch (Exception ex)
  746. {
  747. LOG.Error(ex.Message, ex);
  748. }
  749. }
  750. #endregion login part
  751. public void Logout()
  752. {
  753. this.OnLogoutCommand();
  754. }
  755. public void OnLogoutCommand()
  756. {
  757. WindowManager windowmanager = new WindowManager();
  758. var logoffViewmodel = new LogoffViewModel();
  759. windowmanager.ShowDialog(logoffViewmodel);
  760. BaseApp.Instance.UserMode = logoffViewmodel.DialogResult;
  761. switch (logoffViewmodel.DialogResult)
  762. {
  763. case UserMode.Logoff:
  764. BaseApp.Instance.UserMode = UserMode.Logoff;
  765. if (BaseApp.Instance.UserContext.IsLogin)
  766. {
  767. try
  768. {
  769. AccountClient.Instance.Service.LogoutEx(BaseApp.Instance.UserContext.LoginName, BaseApp.Instance.UserContext.LoginId);
  770. BaseApp.Instance.UserContext.IsLogin = false;
  771. LOG.Info(string.Format("{0} logoff as {1}", BaseApp.Instance.UserContext.LoginName, BaseApp.Instance.UserContext.RoleName));
  772. }
  773. catch (Exception exp)
  774. {
  775. LOG.Write(exp);
  776. }
  777. }
  778. IsLogin = false; //no independent login page
  779. break;
  780. case UserMode.Exit:
  781. AccountClient.Instance.Service.LogoutEx(BaseApp.Instance.UserContext.LoginName, BaseApp.Instance.UserContext.LoginId);
  782. BaseApp.Instance.UserMode = UserMode.Exit;
  783. LOG.Info(string.Format("{0} exit as {1}", BaseApp.Instance.UserContext.LoginName, BaseApp.Instance.UserContext.RoleName));
  784. MsgPool.TerminateAll();
  785. this.TryClose();
  786. break;
  787. case UserMode.Shutdown:
  788. AccountClient.Instance.Service.LogoutEx(BaseApp.Instance.UserContext.LoginName, BaseApp.Instance.UserContext.LoginId);
  789. ShutdownWindow = new ShutdownViewModel();
  790. ShutdownThread = ShutdownExecute;
  791. windowmanager.ShowWindow(ShutdownWindow);
  792. ShutdownThread.BeginInvoke(ShutdownCallBack, ShutdownThread);
  793. break;
  794. }
  795. }
  796. public void Reset()
  797. {
  798. _trigGauge.RST = true;
  799. _trigAlarm.RST = true;
  800. _trigPMAStatsAlarm.RST = true;
  801. _trigPMBStatsAlarm.RST = true;
  802. _trigPMAStatsWarning.RST = true;
  803. _trigPMBStatsWarning.RST = true;
  804. InvokeClient.Instance.Service.DoOperation("System.Reset");
  805. this.ResetAlarmList();
  806. }
  807. public void BuzzerOff()
  808. {
  809. InvokeClient.Instance.Service.DoOperation($"{ModuleName.EFEM}.{EfemOperation.TurnOffBuzzer}");
  810. }
  811. public void FAEnable()
  812. {
  813. InvokeClient.Instance.Service.DoOperation($"FACommand", "FAEnable");
  814. }
  815. public void FADisable()
  816. {
  817. InvokeClient.Instance.Service.DoOperation($"FACommand", "FADisable");
  818. }
  819. #region override functions
  820. public void Logoff()
  821. {
  822. BaseApp.Instance.UserMode = UserMode.Logoff;
  823. if (BaseApp.Instance.UserContext.IsLogin)
  824. {
  825. try
  826. {
  827. AccountClient.Instance.Service.LogoutEx(BaseApp.Instance.UserContext.LoginName, BaseApp.Instance.UserContext.LoginId);
  828. BaseApp.Instance.UserContext.IsLogin = false;
  829. LOG.Info(string.Format("{0} logoff as {1}", BaseApp.Instance.UserContext.LoginName, BaseApp.Instance.UserContext.RoleName));
  830. }
  831. catch (Exception exp)
  832. {
  833. LOG.Write(exp);
  834. }
  835. }
  836. IsLogin = false; //no independent login page
  837. Roles = RoleAccountProvider.Instance.GetRoles();
  838. }
  839. private Dictionary<string, int> _permissionMap;
  840. private void ParsePermissions(string permissionString)
  841. {
  842. _permissionMap = permissionString
  843. .Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
  844. .Select(part => part.Split(','))
  845. .Where(arr => arr.Length == 2)
  846. .ToDictionary(
  847. arr => arr[0].Trim(),
  848. arr => int.TryParse(arr[1].Trim(), out var val) ? val : 0);
  849. }
  850. public bool PageEnabled
  851. {
  852. get
  853. {
  854. if (_permissionMap == null || !_permissionMap.TryGetValue("Header", out var level))
  855. return true;
  856. return level == 3;
  857. }
  858. }
  859. protected override bool OnTimer()
  860. {
  861. try
  862. {
  863. base.Poll();
  864. List<Role> roles = RoleAccountProvider.Instance.GetRoles();
  865. if (!string.IsNullOrEmpty(ClientApp.Instance.UserContext.RoleName))
  866. {
  867. //var _Permission = roles.Find(AccountManager.GetSingleRolePermission(RoleName));
  868. //PageEnabled = true;
  869. //var permissions = AccountManager.GetSingleRolePermission(ClientApp.Instance.UserContext.RoleName);
  870. //var permission = ClientApp.Instance.UserContext.Role.MenuPermission;
  871. ParsePermissions(ClientApp.Instance.UserContext.Role.MenuPermission);
  872. Role role = roles.Find(x => x.RoleName == ClientApp.Instance.UserContext.RoleName);
  873. LogoutTime = role.LogoutTime;
  874. IsAutoLogout = role.IsAutoLogout;
  875. //NotifyOfPropertyChange(() => PageEnabled);
  876. int intervaltime = GetLastInputTime();
  877. //if (System.DateTime.Now >= ClientApp.Instance.UserContext.LoginTime.AddMinutes(LogoutTime) && IsLogin && IsAutoLogout)
  878. if (intervaltime >= LogoutTime * 60 && IsLogin && IsAutoLogout)
  879. Logoff();
  880. }
  881. }
  882. catch (Exception ex)
  883. {
  884. LOG.Error(ex.Message);
  885. }
  886. return true;
  887. }
  888. public override void CanClose(Action<bool> callback)
  889. {
  890. if (BaseApp.Instance.UserMode == UserMode.Normal)
  891. {
  892. callback(false);
  893. Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, (ThreadStart)delegate
  894. {
  895. this.OnLogoutCommand();
  896. });
  897. }
  898. else
  899. callback(true);
  900. }
  901. protected override void OnInitialize()
  902. {
  903. //display system version or other info...(JetPlasma)
  904. this.DisplayName = "";
  905. base.OnInitialize();
  906. this.StartTimer();
  907. DrawSciChart();
  908. //TODO, Login
  909. //Login("admin", new PasswordBox() { Password = "admin" }, new Role("0", "Manager", false, 1000, ""));
  910. }
  911. protected override void OnActivate()
  912. {
  913. base.OnActivate();
  914. this.ShowAllEvents();
  915. EnableTimer(true);
  916. }
  917. protected override void InvokeAfterUpdateProperty(Dictionary<string, object> data)
  918. {
  919. base.InvokeAfterUpdateProperty(data);
  920. if (LP1Present == 0 && _lotCompleteDialog.IsDisplayed && _lotCompleteDialog.LP1Visibility==Visibility.Visible)
  921. {
  922. _lotCompleteDialog.LP1LotComplete.Clear();
  923. _lotCompleteDialog.SetVisible("LP1", false);
  924. }
  925. if (LP2Present == 0 && _lotCompleteDialog.IsDisplayed && _lotCompleteDialog.LP2Visibility == Visibility.Visible)
  926. {
  927. _lotCompleteDialog.LP2LotComplete.Clear();
  928. _lotCompleteDialog.SetVisible("LP2", false);
  929. }
  930. if (_lotCompleteDialog.LP1Visibility==Visibility.Hidden && _lotCompleteDialog.LP2Visibility == Visibility.Hidden && _lotCompleteDialog.IsDisplayed)
  931. {
  932. _lotCompleteDialog.TryClose(true);
  933. _lotCompleteDialog.IsDisplayed = false;
  934. }
  935. }
  936. void DrawSciChart()
  937. {
  938. // Create the chart surface
  939. var sciChartSurface = new SciChartSurface();
  940. // Create the X and Y Axis
  941. var xAxis = new NumericAxis() { AxisTitle = "Number of Samples (per series)" };
  942. var yAxis = new NumericAxis() { AxisTitle = "Value" };
  943. sciChartSurface.XAxis = xAxis;
  944. sciChartSurface.YAxis = yAxis;
  945. // Specify Interactivity Modifiers
  946. sciChartSurface.ChartModifier = new ModifierGroup(new RubberBandXyZoomModifier(), new ZoomExtentsModifier());
  947. // Add annotation hints to the user
  948. var textAnnotation = new TextAnnotation()
  949. {
  950. Text = "Hello World!",
  951. X1 = 5.0,
  952. Y1 = 5.0
  953. };
  954. sciChartSurface.Annotations.Add(textAnnotation);
  955. }
  956. protected override void OnViewLoaded(object view)
  957. {
  958. base.OnViewLoaded(view);
  959. this._view = view as MainView;
  960. this._view.tbLoginName.Focus();
  961. }
  962. protected override void OnDeactivate(bool close)
  963. {
  964. base.OnDeactivate(close);
  965. EnableTimer(false);
  966. }
  967. #endregion override functions
  968. #region
  969. #region Sync ShutDown Thread
  970. public delegate void ShutDownSysncThread();
  971. private ShutDownSysncThread ShutdownThread = null;
  972. private ShutdownViewModel ShutdownWindow = null;
  973. private void ShutdownExecute()
  974. {
  975. MsgPool.TerminateAll();
  976. BaseApp.Instance.UserMode = UserMode.Shutdown;
  977. BaseApp.Instance.UserContext.IsLogin = false;
  978. LOG.Info(string.Format("{0} shutdown as {1}", BaseApp.Instance.UserContext.LoginName, BaseApp.Instance.UserContext.RoleName));
  979. this.TryClose();
  980. }
  981. private void ShutdownCallBack(IAsyncResult result)
  982. {
  983. if (ShutdownWindow != null)
  984. {
  985. ShutdownWindow.TryClose();
  986. }
  987. ShutdownThread.EndInvoke(result);
  988. }
  989. #endregion Sync ShutDown Thread
  990. #region Menu Control and page switch
  991. private void InitMenu()
  992. {
  993. this.MenuItems = BaseApp.Instance.MenuManager.MenuItems;
  994. this.HistoryMenus = new ObservableCollection<AppMenu>();
  995. if (this.MenuItems.Count > 0)
  996. {
  997. foreach (AppMenu menuitem in this.MenuItems)
  998. {
  999. if (menuitem.MenuItems.Count > 0)
  1000. {
  1001. this.SwitchMenuItem(menuitem.MenuItems[0]);
  1002. break;
  1003. }
  1004. }
  1005. }
  1006. }
  1007. public void MainSwitchMenuItem(AppMenu menuViewItem)
  1008. {
  1009. if (menuViewItem.MenuItems.Count > 0)
  1010. {
  1011. if (menuViewItem.LastSelectedSubMenu != null)
  1012. SwitchMenuItem(menuViewItem.LastSelectedSubMenu);
  1013. else
  1014. SwitchMenuItem(menuViewItem.MenuItems[0]);
  1015. }
  1016. }
  1017. public void SwitchMenuItem(AppMenu menuViewItem, object queryFilter = null)
  1018. {
  1019. if (menuViewItem.ViewModel != null && menuViewItem.ViewModel != string.Empty)
  1020. {
  1021. if (menuViewItem.Model == null)
  1022. {
  1023. menuViewItem.Model = (BaseModel)AssemblyUtil.CreateInstance(AssemblyUtil.GetType(menuViewItem.ViewModel));
  1024. ((BaseModel)menuViewItem.Model).Permission = menuViewItem.Permission;
  1025. ((BaseModel)menuViewItem.Model).Token = BaseApp.Instance.UserContext.Token;
  1026. if (menuViewItem.Model is ISupportMultipleSystem)
  1027. (menuViewItem.Model as ISupportMultipleSystem).SystemName = menuViewItem.System;
  1028. if (menuViewItem.Model is RFCalibrationViewModel)
  1029. {
  1030. var viewModel = (menuViewItem.Model as RFCalibrationViewModel);
  1031. if (viewModel.CustomParameter == null)
  1032. viewModel.CustomParameter = new CustomCalibration(viewModel.SystemName);
  1033. }
  1034. }
  1035. this.ActivateItem(((BaseModel)menuViewItem.Model));
  1036. CurrentViewModel = ((BaseModel)menuViewItem.Model);
  1037. if (((BaseModel)menuViewItem.Model).Page != PageID.MAX_PAGE)
  1038. BaseApp.Instance.SetCurrentPage(((BaseModel)menuViewItem.Model).Page);
  1039. this.HandleSubAndHistoryMenu(menuViewItem);
  1040. if (this._currentMenuItem != null)
  1041. {
  1042. this._currentMenuItem.Selected = false;
  1043. this._currentMenuItem.Parent.Selected = false;
  1044. }
  1045. menuViewItem.Selected = true;
  1046. menuViewItem.Parent.Selected = true;
  1047. menuViewItem.Parent.LastSelectedSubMenu = menuViewItem;
  1048. this._currentMenuItem = menuViewItem;
  1049. if (queryFilter != null)
  1050. {
  1051. Task.Delay(1000).ContinueWith((x) =>
  1052. {
  1053. var viewModel = (menuViewItem.Model as Models.History.ProcessHistory.ProcessHistoryViewModel);
  1054. viewModel.Query(queryFilter);
  1055. });
  1056. }
  1057. }
  1058. }
  1059. private void HandleSubAndHistoryMenu(AppMenu menuitem)
  1060. {
  1061. this.SubMenuItems = menuitem.Parent.MenuItems;
  1062. if (!this.HistoryMenus.Contains(menuitem))
  1063. {
  1064. if (this.HistoryMenus.Count >= 8)
  1065. this.HistoryMenus.RemoveAt(7);
  1066. this.HistoryMenus.Insert(0, menuitem);
  1067. }
  1068. else
  1069. {
  1070. this.HistoryMenus.Remove(menuitem);
  1071. this.HistoryMenus.Insert(0, menuitem);
  1072. }
  1073. }
  1074. public bool SwitchPage(string firstLevelMenuID, string secondLevelMenuID, object queryFilter = null)
  1075. {
  1076. foreach (AppMenu menuitem in BaseApp.Instance.MenuManager.MenuItems)
  1077. {
  1078. if (menuitem.MenuID == firstLevelMenuID)
  1079. {
  1080. foreach (AppMenu menu in menuitem.MenuItems)
  1081. {
  1082. if (menu.MenuID == secondLevelMenuID)
  1083. {
  1084. SwitchMenuItem(menu, queryFilter);
  1085. return true;
  1086. }
  1087. }
  1088. }
  1089. }
  1090. return false;
  1091. }
  1092. #endregion Menu Control and page switch
  1093. #region Refresh Date Time on page
  1094. private void StartTimer()
  1095. {
  1096. System.Windows.Threading.DispatcherTimer myDispatcherTimer =
  1097. new System.Windows.Threading.DispatcherTimer();
  1098. myDispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 1000);
  1099. myDispatcherTimer.Tick += new EventHandler(Each_Tick);
  1100. myDispatcherTimer.Start();
  1101. }
  1102. public void Each_Tick(object o, EventArgs sender)
  1103. {
  1104. this.NowDateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
  1105. this.NotifyOfPropertyChange("NowDateTime");
  1106. }
  1107. #endregion Refresh Date Time on page
  1108. #endregion
  1109. public string NowDateTime { get; set; }
  1110. private bool _IsLogin = false;
  1111. public bool IsLogin
  1112. {
  1113. get { return _IsLogin; }
  1114. set { _IsLogin = value; NotifyOfPropertyChange("IsLogin"); }
  1115. }
  1116. private List<Role> roles;
  1117. public List<Role> Roles
  1118. {
  1119. get { return this.roles; }
  1120. set { this.roles = value; this.RaisePropertyChangedEventImmediately("Roles"); }
  1121. }
  1122. private ICommand menuItemClickCommand;
  1123. public ICommand MenuItemClickCommand
  1124. {
  1125. get
  1126. {
  1127. if (this.menuItemClickCommand == null)
  1128. this.menuItemClickCommand = new BaseCommand<AppMenu>((AppMenu menuViewItem) => this.SwitchMenuItem(menuViewItem));
  1129. return this.menuItemClickCommand;
  1130. }
  1131. }
  1132. private ICommand mainmenuItemClickCommand;
  1133. public ICommand MainMenuItemClickCommand
  1134. {
  1135. get
  1136. {
  1137. if (this.mainmenuItemClickCommand == null)
  1138. this.mainmenuItemClickCommand = new BaseCommand<AppMenu>((AppMenu menuViewItem) => this.MainSwitchMenuItem(menuViewItem));
  1139. return this.mainmenuItemClickCommand;
  1140. }
  1141. }
  1142. public List<AppMenu> MenuItems
  1143. {
  1144. get { return this.menuItems; }
  1145. set { this.menuItems = value; this.NotifyOfPropertyChange("MenuItems"); }
  1146. }
  1147. public List<AppMenu> SubMenuItems
  1148. {
  1149. get { return this.subMenuItems; }
  1150. set { this.subMenuItems = value; this.NotifyOfPropertyChange("SubMenuItems"); }
  1151. }
  1152. public ObservableCollection<AppMenu> HistoryMenus
  1153. {
  1154. get { return this.historyItems; }
  1155. set { this.historyItems = value; this.NotifyOfPropertyChange("HistoryMenus"); }
  1156. }
  1157. public string Context
  1158. {
  1159. get { return this.context; }
  1160. set { this.context = value; this.NotifyOfPropertyChange("Context"); }
  1161. }
  1162. public BaseModel CurrentViewModel { get; private set; }
  1163. public UserContext User { get { return BaseApp.Instance.UserContext; } }
  1164. private AppMenu _currentMenuItem;
  1165. private List<AppMenu> menuItems;
  1166. private List<AppMenu> subMenuItems;
  1167. private ObservableCollection<AppMenu> historyItems;
  1168. private string context;
  1169. private MainView _view;
  1170. private Dictionary<Type, BaseModel> _models;
  1171. }
  1172. }