MainViewModel.cs 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413
  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.Dialog;
  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("获取RT数据失败");
  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("由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("由RT返回的数据更新失败" + key, ex);
  323. }
  324. }
  325. });
  326. }
  327. }
  328. public class TerminalItem
  329. {
  330. public string TerminalTime { get; set; }
  331. public string TerminalText { get; set; }
  332. }
  333. public class MainViewModel : TimeredMainViewModel
  334. {
  335. public bool IsAutoLogout { get; set; }
  336. public int LogoutTime { get; set; }
  337. public ObservableCollection<EventItem> WarnEventLogList { get; set; }
  338. public ObservableCollection<EventItem> EventLogList { get; set; }
  339. public ObservableCollection<TerminalItem> TerminalLogList { get; set; }
  340. public TerminalDialogViewModel _TerminalDialog { get; set; }
  341. public bool ShowTerminalDialog;
  342. public Visibility AllEventsVisibility { get; set; }
  343. public Visibility WarnEventsVisibility { get; set; }
  344. public bool IsAlarmListOpen { get; set; }
  345. [Subscription("Rt.Status")]
  346. public string RtStatus { get; set; }
  347. public string RtStatusBackground
  348. {
  349. get { return GetUnitStatusBackground(RtStatus); }
  350. }
  351. [Subscription("EFEM.FsmState")]
  352. public string EfemStatus { get; set; }
  353. public string EfemStatusBackground
  354. {
  355. get { return GetUnitStatusBackground(EfemStatus); }
  356. }
  357. public string HostStatusBackground
  358. {
  359. get { return $"{HostCommunicationStatus}"; }
  360. }
  361. [Subscription("System.ControlStatus")]
  362. public string HostControlStatus
  363. {
  364. get;
  365. set;
  366. }
  367. public string HostControlStatusBackground
  368. {
  369. get
  370. {
  371. switch (HostControlStatus)
  372. {
  373. case "Unknown":
  374. return "Yellow";
  375. case "EquipmentOffline":
  376. case "AttemptOnline":
  377. case "HostOffline":
  378. return "Transparent";
  379. case "OnlineLocal":
  380. case "OnlineRemote":
  381. return "LawnGreen";
  382. default:
  383. return "Yellow";
  384. }
  385. }
  386. }
  387. [Subscription("System.CommunicationStatus")]
  388. public string HostCommunicationStatus
  389. {
  390. get;
  391. set;
  392. }
  393. /// Disabled = 0,
  394. /// Enabled = 1,
  395. /// EnabledNotCommunicating = 2,
  396. /// EnabledCommunicating = 3,
  397. /// WaitCRA = 4,
  398. /// WaitDelay = 5,
  399. /// WaitCRFromHost = 6,
  400. public string HostCommunicationStatusBackground
  401. {
  402. get
  403. {
  404. switch (HostCommunicationStatus)
  405. {
  406. case "Disabled":
  407. return "Yellow";
  408. case "Enabled":
  409. case "EnabledNotCommunicating":
  410. case "WaitCRA":
  411. case "WaitDelay":
  412. case "WaitCRFromHost":
  413. return "Transparent";
  414. case "EnabledCommunicating":
  415. return "LawnGreen";
  416. default:
  417. return "Yellow";
  418. }
  419. }
  420. }
  421. public bool IsEnableFAEnable
  422. {
  423. get
  424. {
  425. return HostCommunicationStatus == "Disabled";
  426. }
  427. }
  428. public bool IsDisableFAEnable
  429. {
  430. get
  431. {
  432. return HostCommunicationStatus != "Disabled";
  433. }
  434. }
  435. [Subscription("PMA.FsmState")]
  436. public string PMAStatus { get; set; }
  437. public string PMAStatusBackground
  438. {
  439. get { return GetUnitStatusBackground(PMAStatus); }
  440. }
  441. [Subscription("PMB.FsmState")]
  442. public string PMBStatus { get; set; }
  443. public string PMBStatusBackground
  444. {
  445. get { return GetUnitStatusBackground(PMBStatus); }
  446. }
  447. [Subscription("LP1.CassettePresent")]
  448. public int LP1Present { get; set; }
  449. [Subscription("LP2.CassettePresent")]
  450. public int LP2Present { get; set; }
  451. [Subscription("PMA.IsOnline")]
  452. public bool PMAIsOnline { get; set; }
  453. public string PMA_TopFrame_TextColor
  454. {
  455. get { return PMAIsOnline ? "LimeGreen" : "White"; }
  456. }
  457. [Subscription("PMB.IsOnline")]
  458. public bool PMBIsOnline { get; set; }
  459. public string PMB_TopFrame_TextColor
  460. {
  461. get { return PMBIsOnline ? "LimeGreen" : "White"; }
  462. }
  463. [Subscription("System.SignalTower.DeviceData")]
  464. public AITSignalTowerData SignalTowerData
  465. {
  466. get;
  467. set;
  468. }
  469. private string _lastLoginName;
  470. public string LastLoginName
  471. {
  472. get { return _lastLoginName; }
  473. set
  474. {
  475. _lastLoginName = value;
  476. this.NotifyOfPropertyChange("LastLoginName");
  477. }
  478. }
  479. private string _loginName;
  480. public string LoginName
  481. {
  482. get { return _loginName; }
  483. set
  484. {
  485. _loginName = value;
  486. this.NotifyOfPropertyChange("LoginName");
  487. }
  488. }
  489. private string _roleName;
  490. public string RoleName
  491. {
  492. get { return _roleName; }
  493. set
  494. {
  495. _roleName = value;
  496. this.NotifyOfPropertyChange("RoleName");
  497. }
  498. }
  499. [StructLayout(LayoutKind.Sequential)]
  500. internal struct LASTINPUTINFO
  501. {
  502. [MarshalAs(UnmanagedType.U4)]
  503. public int cbSize;
  504. [MarshalAs(UnmanagedType.U4)]
  505. public int dwTime;
  506. }
  507. [DllImport("user32.dll")]
  508. internal static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
  509. /// <summary>
  510. /// 获取鼠标键盘不活动的时间
  511. /// </summary>
  512. /// <returns>结果</returns>
  513. public static int GetLastInputTime()
  514. {
  515. LASTINPUTINFO lastInputInfo = new LASTINPUTINFO();
  516. lastInputInfo.cbSize = Marshal.SizeOf(lastInputInfo);
  517. lastInputInfo.dwTime = 0;
  518. int idleTime = 0;
  519. if (GetLastInputInfo(ref lastInputInfo))
  520. {
  521. idleTime = Environment.TickCount - lastInputInfo.dwTime;
  522. }
  523. return ((idleTime > 0) ? (idleTime / 1000) : 0);
  524. }
  525. public MainViewModel()
  526. {
  527. BaseApp.Instance.Initialize();
  528. ((VirgoUI.Client.ClientApp)BaseApp.Instance).ViewModelSwitcher = this;
  529. this._models = new Dictionary<Type, BaseModel>();
  530. //for login part
  531. Roles = RoleAccountProvider.Instance.GetRoles();
  532. EventLogList = new ObservableCollection<EventItem>();
  533. EventClient.Instance.OnEvent += Instance_OnEvent;
  534. EventClient.Instance.OnDisconnectedWithRT += Instance_OnDisconnectedWithRT;
  535. EventClient.Instance.Start();
  536. WarnEventLogList = new ObservableCollection<EventItem>();
  537. TerminalLogList = new ObservableCollection<TerminalItem>();
  538. ShowTerminalDialog = (bool)QueryDataClient.Instance.Service.GetConfig($"System.FA.TerminalMessageShowDialog");
  539. _TerminalDialog = new TerminalDialogViewModel();
  540. SoftwareVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
  541. }
  542. private void Instance_OnDisconnectedWithRT()
  543. {
  544. MessageBox.Show("Disconnected with RT, UI will exit", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
  545. Environment.Exit(0);
  546. }
  547. public void ShowAlarmEvents()
  548. {
  549. AllEventsVisibility = Visibility.Hidden;
  550. WarnEventsVisibility = Visibility.Visible;
  551. this.NotifyOfPropertyChange("AllEventsVisibility");
  552. this.NotifyOfPropertyChange("WarnEventsVisibility");
  553. }
  554. public void ShowAllEvents()
  555. {
  556. AllEventsVisibility = Visibility.Visible;
  557. WarnEventsVisibility = Visibility.Hidden;
  558. this.NotifyOfPropertyChange("AllEventsVisibility");
  559. this.NotifyOfPropertyChange("WarnEventsVisibility");
  560. }
  561. private void Instance_OnEvent(EventItem obj)
  562. {
  563. switch (obj.Type)
  564. {
  565. case EventType.EventUI_Notify:
  566. LogEvent(obj);
  567. break;
  568. case EventType.Dialog_Nofity:
  569. PopDialog(obj);
  570. break;
  571. case EventType.KickOut_Notify:
  572. break;
  573. case EventType.Sound_Notify:
  574. break;
  575. case EventType.UIMessage_Notify:
  576. //PopUIMessage(obj);
  577. break;
  578. }
  579. }
  580. void PopDialog(EventItem item)
  581. {
  582. Application.Current.Dispatcher.Invoke(new System.Action(() =>
  583. {
  584. switch (item.Level)
  585. {
  586. case EventLevel.Alarm:
  587. MessageBoxEx.ShowError(item.Description, item.Explaination);
  588. break;
  589. case EventLevel.Warning:
  590. MessageBoxEx.ShowWarning(item.Description, item.Explaination);
  591. break;
  592. case EventLevel.Information:
  593. MessageBoxEx.ShowInfo(item.Description, item.Explaination);
  594. break;
  595. case EventLevel.InformationNoDelay:
  596. ShowLotComplete(item.Explaination);
  597. //MessageBoxEx.ShowInfoNoDelay(item.Description, item.Explaination);
  598. break;
  599. }
  600. }));
  601. }
  602. LotCompleteDialogViewModel _lotCompleteDialog = new LotCompleteDialogViewModel();
  603. void ShowLotComplete(string result)
  604. {
  605. string[] info = result.Split(';');
  606. if (info.Length > 5)
  607. {
  608. var module = info[0];
  609. _lotCompleteDialog.DisplayName = "Information";
  610. //LP;WaferSize;Lot;Number;Start;End;
  611. if (module == "LP1")
  612. {
  613. _lotCompleteDialog.LP1LotComplete.Module = "LP1";
  614. _lotCompleteDialog.LP1LotComplete.LotID = info[2];
  615. _lotCompleteDialog.LP1LotComplete.WaferNumber = info[3];
  616. _lotCompleteDialog.LP1LotComplete.StartTime = info[4];
  617. _lotCompleteDialog.LP1LotComplete.EndTime = info[5];
  618. switch (info[1])
  619. {
  620. case "WS3":
  621. _lotCompleteDialog.LP1LotComplete.WaferSize = $"WS{QueryDataClient.Instance.Service.GetConfig($"System.SmallWafer")}";
  622. break;
  623. case "WS4":
  624. _lotCompleteDialog.LP1LotComplete.WaferSize = $"WS{QueryDataClient.Instance.Service.GetConfig($"System.MidWafer")}";
  625. break;
  626. case "WS6":
  627. _lotCompleteDialog.LP1LotComplete.WaferSize = $"WS{QueryDataClient.Instance.Service.GetConfig($"System.BigWafer")}";
  628. break;
  629. }
  630. _lotCompleteDialog.LP1LotComplete.InvokePropertyChanged();
  631. }
  632. if (module == "LP2")
  633. {
  634. _lotCompleteDialog.LP2LotComplete.Module = "LP2";
  635. _lotCompleteDialog.LP2LotComplete.LotID = info[2];
  636. _lotCompleteDialog.LP2LotComplete.WaferNumber = info[3];
  637. _lotCompleteDialog.LP2LotComplete.StartTime = info[4];
  638. _lotCompleteDialog.LP2LotComplete.EndTime = info[5];
  639. switch (info[1])
  640. {
  641. case "WS3":
  642. _lotCompleteDialog.LP2LotComplete.WaferSize = $"WS{QueryDataClient.Instance.Service.GetConfig($"System.SmallWafer")}";
  643. break;
  644. case "WS4":
  645. _lotCompleteDialog.LP2LotComplete.WaferSize = $"WS{QueryDataClient.Instance.Service.GetConfig($"System.MidWafer")}";
  646. break;
  647. case "WS6":
  648. _lotCompleteDialog.LP2LotComplete.WaferSize = $"WS{QueryDataClient.Instance.Service.GetConfig($"System.BigWafer")}";
  649. break;
  650. }
  651. _lotCompleteDialog.LP2LotComplete.InvokePropertyChanged();
  652. }
  653. _lotCompleteDialog.SetVisible(module, true);
  654. }
  655. if (!_lotCompleteDialog.IsDisplayed)
  656. {
  657. _lotCompleteDialog.IsDisplayed = true;
  658. Task.Run(() =>
  659. {
  660. Application.Current.Dispatcher.Invoke(() =>
  661. {
  662. WindowManager wm = new WindowManager();
  663. bool? bret = wm.ShowDialog(_lotCompleteDialog);
  664. if ((bool)bret)
  665. {
  666. }
  667. _lotCompleteDialog.IsDisplayed = false;
  668. });
  669. });
  670. }
  671. }
  672. void LogEvent(EventItem obj)
  673. {
  674. if (obj.Type != EventType.EventUI_Notify)
  675. return;
  676. Application.Current.Dispatcher.Invoke(() =>
  677. {
  678. while (EventLogList.Count > 100)
  679. {
  680. EventLogList.RemoveAt(0);
  681. }
  682. EventLogList.Add(obj);
  683. if (obj.Level == EventLevel.Alarm)
  684. this.WarnEventLogList.Add(obj);
  685. });
  686. if (obj.EventEnum == "TerminalMessage"&& ShowTerminalDialog)
  687. {
  688. Task.Run(() =>
  689. {
  690. Application.Current.Dispatcher.Invoke(() =>
  691. {
  692. if (TerminalLogList.Count > 100)
  693. {
  694. TerminalLogList.RemoveAt(0);
  695. }
  696. TerminalLogList.Add(new TerminalItem()
  697. {
  698. TerminalTime = System.DateTime.Now.ToString(),
  699. TerminalText = obj.Description
  700. });
  701. _TerminalDialog._terminalLogList = TerminalLogList;
  702. //_TerminalDialog._terminalLogList.Clear();
  703. //for(int i = TerminalLogList.Count - 1; i > 0; i--)
  704. //{
  705. // _TerminalDialog._terminalLogList.Add(TerminalLogList[i]);
  706. //}
  707. WindowManager wm = new WindowManager();
  708. if (!_TerminalDialog.IsDisplayed)
  709. {
  710. _TerminalDialog.IsDisplayed = true;
  711. bool? bret = wm.ShowDialog(_TerminalDialog);
  712. if ((bool)bret)
  713. {
  714. _TerminalDialog.IsDisplayed = false;
  715. }
  716. else
  717. {
  718. _TerminalDialog.IsDisplayed = false;
  719. }
  720. }
  721. });
  722. });
  723. }
  724. if (this.WarnEventLogList.Count() > 1)
  725. this.IsAlarmListOpen = true;
  726. }
  727. void ResetAlarmList()
  728. {
  729. this.WarnEventLogList.Clear();
  730. }
  731. #region login part
  732. public void Enter(KeyEventArgs args, string loginName, PasswordBox password, Role role)
  733. {
  734. if (args.Key == Key.Enter)
  735. this.Login(loginName, password, role);
  736. }
  737. public void Login(string loginName, PasswordBox password, Role role)
  738. {
  739. try
  740. {
  741. LoginResult result = AccountClient.Instance.Service.LoginEx(loginName, password.Password, role.RoleID);
  742. if (result.ActSucc)
  743. {
  744. ClientApp.Instance.UserContext.LoginId = result.SessionId;
  745. ClientApp.Instance.UserMode = UserMode.Normal;
  746. ClientApp.Instance.UserContext.LoginName = loginName;
  747. ClientApp.Instance.UserContext.Role = role;
  748. ClientApp.Instance.UserContext.RoleID = role.RoleID;
  749. ClientApp.Instance.UserContext.RoleName = role.RoleName;
  750. ClientApp.Instance.UserContext.LoginTime = DateTime.Now;
  751. //ClientApp.Instance.UserContext.Token = token;
  752. ClientApp.Instance.UserContext.LastAccessTime = DateTime.Now;
  753. ClientApp.Instance.UserContext.IsLogin = true;
  754. //Load menu by role
  755. //filer menu if necessary...
  756. ClientApp.Instance.MenuManager.LoadMenu(RoleAccountProvider.Instance.GetMenusByRole(role.RoleID, ClientApp.Instance.MenuLoader.MenuList));
  757. IsAutoLogout = role.IsAutoLogout;
  758. LogoutTime = role.LogoutTime;
  759. InitMenu(); //bind menu to main view
  760. IsLogin = true; //control the display logic of main view
  761. //main view is common page, need register keys with true flag
  762. ClientApp.Instance.StatesManager.Register(new List<string>() { "System.RtStatus" }, true);
  763. LoginName = loginName;
  764. RoleName = role.RoleName;
  765. LOG.Info(string.Format("{0} login as {1}", loginName, role.RoleName));
  766. }
  767. else
  768. {
  769. Enum.TryParse(result.Description, out AuthorizeResult errCode);
  770. switch (errCode)
  771. {
  772. case AuthorizeResult.None:
  773. DialogBox.ShowError("Not connected with RT.");
  774. break;
  775. case AuthorizeResult.WrongPwd:
  776. DialogBox.ShowError("Invalid password.");
  777. break;
  778. case AuthorizeResult.HasLogin:
  779. DialogBox.ShowError("{0} has already logged in.", loginName);
  780. break;
  781. case AuthorizeResult.NoMatchRole:
  782. DialogBox.ShowError("{0} does not match {1} role.", loginName, role.RoleName);
  783. break;
  784. case AuthorizeResult.NoMatchUser:
  785. DialogBox.ShowError("{0} does not exists.", loginName);
  786. break;
  787. case AuthorizeResult.NoSession:
  788. DialogBox.ShowError("The current session is invalid.");
  789. break;
  790. }
  791. }
  792. password.Clear();
  793. }
  794. catch (Exception ex)
  795. {
  796. LOG.Error(ex.Message, ex);
  797. }
  798. }
  799. #endregion login part
  800. public void Logout()
  801. {
  802. this.OnLogoutCommand();
  803. }
  804. public void OnLogoutCommand()
  805. {
  806. WindowManager windowmanager = new WindowManager();
  807. var logoffViewmodel = new LogoffViewModel();
  808. windowmanager.ShowDialog(logoffViewmodel);
  809. BaseApp.Instance.UserMode = logoffViewmodel.DialogResult;
  810. switch (logoffViewmodel.DialogResult)
  811. {
  812. case UserMode.Logoff:
  813. BaseApp.Instance.UserMode = UserMode.Logoff;
  814. if (BaseApp.Instance.UserContext.IsLogin)
  815. {
  816. try
  817. {
  818. AccountClient.Instance.Service.LogoutEx(BaseApp.Instance.UserContext.LoginName, BaseApp.Instance.UserContext.LoginId);
  819. BaseApp.Instance.UserContext.IsLogin = false;
  820. LOG.Info(string.Format("{0} logoff as {1}", BaseApp.Instance.UserContext.LoginName, BaseApp.Instance.UserContext.RoleName));
  821. }
  822. catch (Exception exp)
  823. {
  824. LOG.Write(exp);
  825. }
  826. }
  827. IsLogin = false; //no independent login page
  828. break;
  829. case UserMode.Exit:
  830. AccountClient.Instance.Service.LogoutEx(BaseApp.Instance.UserContext.LoginName, BaseApp.Instance.UserContext.LoginId);
  831. BaseApp.Instance.UserMode = UserMode.Exit;
  832. LOG.Info(string.Format("{0} exit as {1}", BaseApp.Instance.UserContext.LoginName, BaseApp.Instance.UserContext.RoleName));
  833. MsgPool.TerminateAll();
  834. this.TryClose();
  835. break;
  836. case UserMode.Shutdown:
  837. AccountClient.Instance.Service.LogoutEx(BaseApp.Instance.UserContext.LoginName, BaseApp.Instance.UserContext.LoginId);
  838. ShutdownWindow = new ShutdownViewModel();
  839. ShutdownThread = ShutdownExecute;
  840. windowmanager.ShowWindow(ShutdownWindow);
  841. ShutdownThread.BeginInvoke(ShutdownCallBack, ShutdownThread);
  842. break;
  843. }
  844. }
  845. public void Reset()
  846. {
  847. _trigGauge.RST = true;
  848. _trigAlarm.RST = true;
  849. _trigPMAStatsAlarm.RST = true;
  850. _trigPMBStatsAlarm.RST = true;
  851. _trigPMAStatsWarning.RST = true;
  852. _trigPMBStatsWarning.RST = true;
  853. InvokeClient.Instance.Service.DoOperation("System.Reset");
  854. this.ResetAlarmList();
  855. }
  856. public void BuzzerOff()
  857. {
  858. InvokeClient.Instance.Service.DoOperation($"{ModuleName.EFEM}.{EfemOperation.TurnOffBuzzer}");
  859. }
  860. public void FAEnable()
  861. {
  862. InvokeClient.Instance.Service.DoOperation($"System.FACommand", "FAEnable");
  863. }
  864. public void FADisable()
  865. {
  866. InvokeClient.Instance.Service.DoOperation($"System.FACommand", "FADisable");
  867. }
  868. #region override functions
  869. public void Logoff()
  870. {
  871. BaseApp.Instance.UserMode = UserMode.Logoff;
  872. if (BaseApp.Instance.UserContext.IsLogin)
  873. {
  874. try
  875. {
  876. AccountClient.Instance.Service.LogoutEx(BaseApp.Instance.UserContext.LoginName, BaseApp.Instance.UserContext.LoginId);
  877. BaseApp.Instance.UserContext.IsLogin = false;
  878. LOG.Info(string.Format("{0} logoff as {1}", BaseApp.Instance.UserContext.LoginName, BaseApp.Instance.UserContext.RoleName));
  879. }
  880. catch (Exception exp)
  881. {
  882. LOG.Write(exp);
  883. }
  884. }
  885. IsLogin = false; //no independent login page
  886. Roles = RoleAccountProvider.Instance.GetRoles();
  887. }
  888. protected override bool OnTimer()
  889. {
  890. try
  891. {
  892. base.Poll();
  893. List<Role> roles = RoleAccountProvider.Instance.GetRoles();
  894. if (!string.IsNullOrEmpty(ClientApp.Instance.UserContext.RoleName))
  895. {
  896. Role role = roles.Find(x => x.RoleName == ClientApp.Instance.UserContext.RoleName);
  897. LogoutTime = role.LogoutTime;
  898. IsAutoLogout = role.IsAutoLogout;
  899. int intervaltime = GetLastInputTime();
  900. //if (System.DateTime.Now >= ClientApp.Instance.UserContext.LoginTime.AddMinutes(LogoutTime) && IsLogin && IsAutoLogout)
  901. if (intervaltime >= LogoutTime * 60 && IsLogin && IsAutoLogout)
  902. Logoff();
  903. }
  904. }
  905. catch (Exception ex)
  906. {
  907. LOG.Error(ex.Message);
  908. }
  909. return true;
  910. }
  911. public override void CanClose(Action<bool> callback)
  912. {
  913. if (BaseApp.Instance.UserMode == UserMode.Normal)
  914. {
  915. callback(false);
  916. Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, (ThreadStart)delegate
  917. {
  918. this.OnLogoutCommand();
  919. });
  920. }
  921. else
  922. callback(true);
  923. }
  924. protected override void OnInitialize()
  925. {
  926. //display system version or other info...
  927. this.DisplayName = "JetPlasma";
  928. base.OnInitialize();
  929. this.StartTimer();
  930. DrawSciChart();
  931. //TODO, Login
  932. //Login("admin", new PasswordBox() { Password = "admin" }, new Role("0", "Manager", false, 1000, ""));
  933. }
  934. protected override void OnActivate()
  935. {
  936. base.OnActivate();
  937. this.ShowAllEvents();
  938. EnableTimer(true);
  939. }
  940. protected override void InvokeAfterUpdateProperty(Dictionary<string, object> data)
  941. {
  942. base.InvokeAfterUpdateProperty(data);
  943. if (LP1Present == 0 && _lotCompleteDialog.IsDisplayed && _lotCompleteDialog.LP1Visibility==Visibility.Visible)
  944. {
  945. _lotCompleteDialog.LP1LotComplete.Clear();
  946. _lotCompleteDialog.SetVisible("LP1", false);
  947. }
  948. if (LP2Present == 0 && _lotCompleteDialog.IsDisplayed && _lotCompleteDialog.LP2Visibility == Visibility.Visible)
  949. {
  950. _lotCompleteDialog.LP2LotComplete.Clear();
  951. _lotCompleteDialog.SetVisible("LP2", false);
  952. }
  953. if (_lotCompleteDialog.LP1Visibility==Visibility.Hidden && _lotCompleteDialog.LP2Visibility == Visibility.Hidden && _lotCompleteDialog.IsDisplayed)
  954. {
  955. _lotCompleteDialog.TryClose(true);
  956. _lotCompleteDialog.IsDisplayed = false;
  957. }
  958. }
  959. void DrawSciChart()
  960. {
  961. // Create the chart surface
  962. var sciChartSurface = new SciChartSurface();
  963. // Create the X and Y Axis
  964. var xAxis = new NumericAxis() { AxisTitle = "Number of Samples (per series)" };
  965. var yAxis = new NumericAxis() { AxisTitle = "Value" };
  966. sciChartSurface.XAxis = xAxis;
  967. sciChartSurface.YAxis = yAxis;
  968. // Specify Interactivity Modifiers
  969. sciChartSurface.ChartModifier = new ModifierGroup(new RubberBandXyZoomModifier(), new ZoomExtentsModifier());
  970. // Add annotation hints to the user
  971. var textAnnotation = new TextAnnotation()
  972. {
  973. Text = "Hello World!",
  974. X1 = 5.0,
  975. Y1 = 5.0
  976. };
  977. sciChartSurface.Annotations.Add(textAnnotation);
  978. }
  979. protected override void OnViewLoaded(object view)
  980. {
  981. base.OnViewLoaded(view);
  982. this._view = view as MainView;
  983. this._view.tbLoginName.Focus();
  984. }
  985. protected override void OnDeactivate(bool close)
  986. {
  987. base.OnDeactivate(close);
  988. EnableTimer(false);
  989. }
  990. #endregion override functions
  991. #region
  992. #region Sync ShutDown Thread
  993. public delegate void ShutDownSysncThread();
  994. private ShutDownSysncThread ShutdownThread = null;
  995. private ShutdownViewModel ShutdownWindow = null;
  996. private void ShutdownExecute()
  997. {
  998. MsgPool.TerminateAll();
  999. BaseApp.Instance.UserMode = UserMode.Shutdown;
  1000. BaseApp.Instance.UserContext.IsLogin = false;
  1001. LOG.Info(string.Format("{0} shutdown as {1}", BaseApp.Instance.UserContext.LoginName, BaseApp.Instance.UserContext.RoleName));
  1002. this.TryClose();
  1003. }
  1004. private void ShutdownCallBack(IAsyncResult result)
  1005. {
  1006. if (ShutdownWindow != null)
  1007. {
  1008. ShutdownWindow.TryClose();
  1009. }
  1010. ShutdownThread.EndInvoke(result);
  1011. }
  1012. #endregion Sync ShutDown Thread
  1013. #region Menu Control and page switch
  1014. private void InitMenu()
  1015. {
  1016. this.MenuItems = BaseApp.Instance.MenuManager.MenuItems;
  1017. this.HistoryMenus = new ObservableCollection<AppMenu>();
  1018. if (this.MenuItems.Count > 0)
  1019. {
  1020. foreach (AppMenu menuitem in this.MenuItems)
  1021. {
  1022. if (menuitem.MenuItems.Count > 0)
  1023. {
  1024. this.SwitchMenuItem(menuitem.MenuItems[0]);
  1025. break;
  1026. }
  1027. }
  1028. }
  1029. }
  1030. public void MainSwitchMenuItem(AppMenu menuViewItem)
  1031. {
  1032. if (menuViewItem.MenuItems.Count > 0)
  1033. {
  1034. if (menuViewItem.LastSelectedSubMenu != null)
  1035. SwitchMenuItem(menuViewItem.LastSelectedSubMenu);
  1036. else
  1037. SwitchMenuItem(menuViewItem.MenuItems[0]);
  1038. }
  1039. }
  1040. public void SwitchMenuItem(AppMenu menuViewItem, object queryFilter = null)
  1041. {
  1042. if (menuViewItem.ViewModel != null && menuViewItem.ViewModel != string.Empty)
  1043. {
  1044. if (menuViewItem.Model == null)
  1045. {
  1046. menuViewItem.Model = (BaseModel)AssemblyUtil.CreateInstance(AssemblyUtil.GetType(menuViewItem.ViewModel));
  1047. ((BaseModel)menuViewItem.Model).Permission = menuViewItem.Permission;
  1048. ((BaseModel)menuViewItem.Model).Token = BaseApp.Instance.UserContext.Token;
  1049. if (menuViewItem.Model is ISupportMultipleSystem)
  1050. (menuViewItem.Model as ISupportMultipleSystem).SystemName = menuViewItem.System;
  1051. //if (menuViewItem.Model is CalibrationTableViewModel)
  1052. //{
  1053. // var viewModel = (menuViewItem.Model as CalibrationTableViewModel);
  1054. // if (viewModel.CustomParameter == null)
  1055. // viewModel.CustomParameter = new CustomCalibration(viewModel.SystemName);
  1056. //}
  1057. }
  1058. this.ActivateItem(((BaseModel)menuViewItem.Model));
  1059. CurrentViewModel = ((BaseModel)menuViewItem.Model);
  1060. if (((BaseModel)menuViewItem.Model).Page != PageID.MAX_PAGE)
  1061. BaseApp.Instance.SetCurrentPage(((BaseModel)menuViewItem.Model).Page);
  1062. this.HandleSubAndHistoryMenu(menuViewItem);
  1063. if (this._currentMenuItem != null)
  1064. {
  1065. this._currentMenuItem.Selected = false;
  1066. this._currentMenuItem.Parent.Selected = false;
  1067. }
  1068. menuViewItem.Selected = true;
  1069. menuViewItem.Parent.Selected = true;
  1070. menuViewItem.Parent.LastSelectedSubMenu = menuViewItem;
  1071. this._currentMenuItem = menuViewItem;
  1072. if (queryFilter != null)
  1073. {
  1074. Task.Delay(1000).ContinueWith((x) =>
  1075. {
  1076. var viewModel = (menuViewItem.Model as Models.History.ProcessHistory.ProcessHistoryViewModel);
  1077. viewModel.Query(queryFilter);
  1078. });
  1079. }
  1080. }
  1081. }
  1082. private void HandleSubAndHistoryMenu(AppMenu menuitem)
  1083. {
  1084. this.SubMenuItems = menuitem.Parent.MenuItems;
  1085. if (!this.HistoryMenus.Contains(menuitem))
  1086. {
  1087. if (this.HistoryMenus.Count >= 8)
  1088. this.HistoryMenus.RemoveAt(7);
  1089. this.HistoryMenus.Insert(0, menuitem);
  1090. }
  1091. else
  1092. {
  1093. this.HistoryMenus.Remove(menuitem);
  1094. this.HistoryMenus.Insert(0, menuitem);
  1095. }
  1096. }
  1097. public bool SwitchPage(string firstLevelMenuID, string secondLevelMenuID, object queryFilter = null)
  1098. {
  1099. foreach (AppMenu menuitem in BaseApp.Instance.MenuManager.MenuItems)
  1100. {
  1101. if (menuitem.MenuID == firstLevelMenuID)
  1102. {
  1103. foreach (AppMenu menu in menuitem.MenuItems)
  1104. {
  1105. if (menu.MenuID == secondLevelMenuID)
  1106. {
  1107. SwitchMenuItem(menu, queryFilter);
  1108. return true;
  1109. }
  1110. }
  1111. }
  1112. }
  1113. return false;
  1114. }
  1115. #endregion Menu Control and page switch
  1116. #region Refresh Date Time on page
  1117. private void StartTimer()
  1118. {
  1119. System.Windows.Threading.DispatcherTimer myDispatcherTimer =
  1120. new System.Windows.Threading.DispatcherTimer();
  1121. myDispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 1000);
  1122. myDispatcherTimer.Tick += new EventHandler(Each_Tick);
  1123. myDispatcherTimer.Start();
  1124. }
  1125. public void Each_Tick(object o, EventArgs sender)
  1126. {
  1127. this.NowDateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
  1128. this.NotifyOfPropertyChange("NowDateTime");
  1129. }
  1130. #endregion Refresh Date Time on page
  1131. #endregion
  1132. public string NowDateTime { get; set; }
  1133. private bool _IsLogin = false;
  1134. public bool IsLogin
  1135. {
  1136. get { return _IsLogin; }
  1137. set { _IsLogin = value; NotifyOfPropertyChange("IsLogin"); }
  1138. }
  1139. private List<Role> roles;
  1140. public List<Role> Roles
  1141. {
  1142. get { return this.roles; }
  1143. set { this.roles = value; this.RaisePropertyChangedEventImmediately("Roles"); }
  1144. }
  1145. private ICommand menuItemClickCommand;
  1146. public ICommand MenuItemClickCommand
  1147. {
  1148. get
  1149. {
  1150. if (this.menuItemClickCommand == null)
  1151. this.menuItemClickCommand = new BaseCommand<AppMenu>((AppMenu menuViewItem) => this.SwitchMenuItem(menuViewItem));
  1152. return this.menuItemClickCommand;
  1153. }
  1154. }
  1155. private ICommand mainmenuItemClickCommand;
  1156. public ICommand MainMenuItemClickCommand
  1157. {
  1158. get
  1159. {
  1160. if (this.mainmenuItemClickCommand == null)
  1161. this.mainmenuItemClickCommand = new BaseCommand<AppMenu>((AppMenu menuViewItem) => this.MainSwitchMenuItem(menuViewItem));
  1162. return this.mainmenuItemClickCommand;
  1163. }
  1164. }
  1165. public List<AppMenu> MenuItems
  1166. {
  1167. get { return this.menuItems; }
  1168. set { this.menuItems = value; this.NotifyOfPropertyChange("MenuItems"); }
  1169. }
  1170. public List<AppMenu> SubMenuItems
  1171. {
  1172. get { return this.subMenuItems; }
  1173. set { this.subMenuItems = value; this.NotifyOfPropertyChange("SubMenuItems"); }
  1174. }
  1175. public ObservableCollection<AppMenu> HistoryMenus
  1176. {
  1177. get { return this.historyItems; }
  1178. set { this.historyItems = value; this.NotifyOfPropertyChange("HistoryMenus"); }
  1179. }
  1180. public string Context
  1181. {
  1182. get { return this.context; }
  1183. set { this.context = value; this.NotifyOfPropertyChange("Context"); }
  1184. }
  1185. public BaseModel CurrentViewModel { get; private set; }
  1186. public UserContext User { get { return BaseApp.Instance.UserContext; } }
  1187. private AppMenu _currentMenuItem;
  1188. private List<AppMenu> menuItems;
  1189. private List<AppMenu> subMenuItems;
  1190. private ObservableCollection<AppMenu> historyItems;
  1191. private string context;
  1192. private MainView _view;
  1193. private Dictionary<Type, BaseModel> _models;
  1194. }
  1195. }