MainViewModel.cs 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372
  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. //private int MenuPermission;
  860. protected override bool OnTimer()
  861. {
  862. try
  863. {
  864. base.Poll();
  865. List<Role> roles = RoleAccountProvider.Instance.GetRoles();
  866. if (!string.IsNullOrEmpty(ClientApp.Instance.UserContext.RoleName))
  867. {
  868. //var _Permission = roles.Find(AccountManager.GetSingleRolePermission(RoleName));
  869. //PageEnabled = true;
  870. //var permissions = AccountManager.GetSingleRolePermission(ClientApp.Instance.UserContext.RoleName);
  871. //var permission = ClientApp.Instance.UserContext.Role.MenuPermission;
  872. ParsePermissions(ClientApp.Instance.UserContext.Role.MenuPermission);
  873. Role role = roles.Find(x => x.RoleName == ClientApp.Instance.UserContext.RoleName);
  874. LogoutTime = role.LogoutTime;
  875. IsAutoLogout = role.IsAutoLogout;
  876. //NotifyOfPropertyChange(() => PageEnabled);
  877. int intervaltime = GetLastInputTime();
  878. //if (System.DateTime.Now >= ClientApp.Instance.UserContext.LoginTime.AddMinutes(LogoutTime) && IsLogin && IsAutoLogout)
  879. if (intervaltime >= LogoutTime * 60 && IsLogin && IsAutoLogout)
  880. Logoff();
  881. }
  882. }
  883. catch (Exception ex)
  884. {
  885. LOG.Error(ex.Message);
  886. }
  887. return true;
  888. }
  889. public override void CanClose(Action<bool> callback)
  890. {
  891. if (BaseApp.Instance.UserMode == UserMode.Normal)
  892. {
  893. callback(false);
  894. Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, (ThreadStart)delegate
  895. {
  896. this.OnLogoutCommand();
  897. });
  898. }
  899. else
  900. callback(true);
  901. }
  902. //public string SystemName { get; set; }
  903. protected override void OnInitialize()
  904. {
  905. //display system version or other info...(JetPlasma)
  906. this.DisplayName = "";
  907. base.OnInitialize();
  908. this.StartTimer();
  909. //MenuPermission = ClientApp.Instance.GetPermission($"MainView{SystemName}");
  910. DrawSciChart();
  911. //TODO, Login
  912. //Login("admin", new PasswordBox() { Password = "admin" }, new Role("0", "Manager", false, 1000, ""));
  913. }
  914. protected override void OnActivate()
  915. {
  916. base.OnActivate();
  917. this.ShowAllEvents();
  918. EnableTimer(true);
  919. }
  920. protected override void InvokeAfterUpdateProperty(Dictionary<string, object> data)
  921. {
  922. base.InvokeAfterUpdateProperty(data);
  923. if (LP1Present == 0 && _lotCompleteDialog.IsDisplayed && _lotCompleteDialog.LP1Visibility==Visibility.Visible)
  924. {
  925. _lotCompleteDialog.LP1LotComplete.Clear();
  926. _lotCompleteDialog.SetVisible("LP1", false);
  927. }
  928. if (LP2Present == 0 && _lotCompleteDialog.IsDisplayed && _lotCompleteDialog.LP2Visibility == Visibility.Visible)
  929. {
  930. _lotCompleteDialog.LP2LotComplete.Clear();
  931. _lotCompleteDialog.SetVisible("LP2", false);
  932. }
  933. if (_lotCompleteDialog.LP1Visibility==Visibility.Hidden && _lotCompleteDialog.LP2Visibility == Visibility.Hidden && _lotCompleteDialog.IsDisplayed)
  934. {
  935. _lotCompleteDialog.TryClose(true);
  936. _lotCompleteDialog.IsDisplayed = false;
  937. }
  938. }
  939. void DrawSciChart()
  940. {
  941. // Create the chart surface
  942. var sciChartSurface = new SciChartSurface();
  943. // Create the X and Y Axis
  944. var xAxis = new NumericAxis() { AxisTitle = "Number of Samples (per series)" };
  945. var yAxis = new NumericAxis() { AxisTitle = "Value" };
  946. sciChartSurface.XAxis = xAxis;
  947. sciChartSurface.YAxis = yAxis;
  948. // Specify Interactivity Modifiers
  949. sciChartSurface.ChartModifier = new ModifierGroup(new RubberBandXyZoomModifier(), new ZoomExtentsModifier());
  950. // Add annotation hints to the user
  951. var textAnnotation = new TextAnnotation()
  952. {
  953. Text = "Hello World!",
  954. X1 = 5.0,
  955. Y1 = 5.0
  956. };
  957. sciChartSurface.Annotations.Add(textAnnotation);
  958. }
  959. protected override void OnViewLoaded(object view)
  960. {
  961. base.OnViewLoaded(view);
  962. this._view = view as MainView;
  963. this._view.tbLoginName.Focus();
  964. }
  965. protected override void OnDeactivate(bool close)
  966. {
  967. base.OnDeactivate(close);
  968. EnableTimer(false);
  969. }
  970. #endregion override functions
  971. #region
  972. #region Sync ShutDown Thread
  973. public delegate void ShutDownSysncThread();
  974. private ShutDownSysncThread ShutdownThread = null;
  975. private ShutdownViewModel ShutdownWindow = null;
  976. private void ShutdownExecute()
  977. {
  978. MsgPool.TerminateAll();
  979. BaseApp.Instance.UserMode = UserMode.Shutdown;
  980. BaseApp.Instance.UserContext.IsLogin = false;
  981. LOG.Info(string.Format("{0} shutdown as {1}", BaseApp.Instance.UserContext.LoginName, BaseApp.Instance.UserContext.RoleName));
  982. this.TryClose();
  983. }
  984. private void ShutdownCallBack(IAsyncResult result)
  985. {
  986. if (ShutdownWindow != null)
  987. {
  988. ShutdownWindow.TryClose();
  989. }
  990. ShutdownThread.EndInvoke(result);
  991. }
  992. #endregion Sync ShutDown Thread
  993. #region Menu Control and page switch
  994. private void InitMenu()
  995. {
  996. this.MenuItems = BaseApp.Instance.MenuManager.MenuItems;
  997. this.HistoryMenus = new ObservableCollection<AppMenu>();
  998. if (this.MenuItems.Count > 0)
  999. {
  1000. foreach (AppMenu menuitem in this.MenuItems)
  1001. {
  1002. if (menuitem.MenuItems.Count > 0)
  1003. {
  1004. this.SwitchMenuItem(menuitem.MenuItems[0]);
  1005. break;
  1006. }
  1007. }
  1008. }
  1009. }
  1010. public void MainSwitchMenuItem(AppMenu menuViewItem)
  1011. {
  1012. if (menuViewItem.MenuItems.Count > 0)
  1013. {
  1014. if (menuViewItem.LastSelectedSubMenu != null)
  1015. SwitchMenuItem(menuViewItem.LastSelectedSubMenu);
  1016. else
  1017. SwitchMenuItem(menuViewItem.MenuItems[0]);
  1018. }
  1019. }
  1020. public void SwitchMenuItem(AppMenu menuViewItem, object queryFilter = null)
  1021. {
  1022. if (menuViewItem.ViewModel != null && menuViewItem.ViewModel != string.Empty)
  1023. {
  1024. if (menuViewItem.Model == null)
  1025. {
  1026. menuViewItem.Model = (BaseModel)AssemblyUtil.CreateInstance(AssemblyUtil.GetType(menuViewItem.ViewModel));
  1027. ((BaseModel)menuViewItem.Model).Permission = menuViewItem.Permission;
  1028. ((BaseModel)menuViewItem.Model).Token = BaseApp.Instance.UserContext.Token;
  1029. if (menuViewItem.Model is ISupportMultipleSystem)
  1030. (menuViewItem.Model as ISupportMultipleSystem).SystemName = menuViewItem.System;
  1031. if (menuViewItem.Model is RFCalibrationViewModel)
  1032. {
  1033. var viewModel = (menuViewItem.Model as RFCalibrationViewModel);
  1034. if (viewModel.CustomParameter == null)
  1035. viewModel.CustomParameter = new CustomCalibration(viewModel.SystemName);
  1036. }
  1037. }
  1038. this.ActivateItem(((BaseModel)menuViewItem.Model));
  1039. CurrentViewModel = ((BaseModel)menuViewItem.Model);
  1040. if (((BaseModel)menuViewItem.Model).Page != PageID.MAX_PAGE)
  1041. BaseApp.Instance.SetCurrentPage(((BaseModel)menuViewItem.Model).Page);
  1042. this.HandleSubAndHistoryMenu(menuViewItem);
  1043. if (this._currentMenuItem != null)
  1044. {
  1045. this._currentMenuItem.Selected = false;
  1046. this._currentMenuItem.Parent.Selected = false;
  1047. }
  1048. menuViewItem.Selected = true;
  1049. menuViewItem.Parent.Selected = true;
  1050. menuViewItem.Parent.LastSelectedSubMenu = menuViewItem;
  1051. this._currentMenuItem = menuViewItem;
  1052. if (queryFilter != null)
  1053. {
  1054. Task.Delay(1000).ContinueWith((x) =>
  1055. {
  1056. var viewModel = (menuViewItem.Model as Models.History.ProcessHistory.ProcessHistoryViewModel);
  1057. viewModel.Query(queryFilter);
  1058. });
  1059. }
  1060. }
  1061. }
  1062. private void HandleSubAndHistoryMenu(AppMenu menuitem)
  1063. {
  1064. this.SubMenuItems = menuitem.Parent.MenuItems;
  1065. if (!this.HistoryMenus.Contains(menuitem))
  1066. {
  1067. if (this.HistoryMenus.Count >= 8)
  1068. this.HistoryMenus.RemoveAt(7);
  1069. this.HistoryMenus.Insert(0, menuitem);
  1070. }
  1071. else
  1072. {
  1073. this.HistoryMenus.Remove(menuitem);
  1074. this.HistoryMenus.Insert(0, menuitem);
  1075. }
  1076. }
  1077. public bool SwitchPage(string firstLevelMenuID, string secondLevelMenuID, object queryFilter = null)
  1078. {
  1079. foreach (AppMenu menuitem in BaseApp.Instance.MenuManager.MenuItems)
  1080. {
  1081. if (menuitem.MenuID == firstLevelMenuID)
  1082. {
  1083. foreach (AppMenu menu in menuitem.MenuItems)
  1084. {
  1085. if (menu.MenuID == secondLevelMenuID)
  1086. {
  1087. SwitchMenuItem(menu, queryFilter);
  1088. return true;
  1089. }
  1090. }
  1091. }
  1092. }
  1093. return false;
  1094. }
  1095. #endregion Menu Control and page switch
  1096. #region Refresh Date Time on page
  1097. private void StartTimer()
  1098. {
  1099. System.Windows.Threading.DispatcherTimer myDispatcherTimer =
  1100. new System.Windows.Threading.DispatcherTimer();
  1101. myDispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 1000);
  1102. myDispatcherTimer.Tick += new EventHandler(Each_Tick);
  1103. myDispatcherTimer.Start();
  1104. }
  1105. public void Each_Tick(object o, EventArgs sender)
  1106. {
  1107. this.NowDateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
  1108. this.NotifyOfPropertyChange("NowDateTime");
  1109. }
  1110. #endregion Refresh Date Time on page
  1111. #endregion
  1112. public string NowDateTime { get; set; }
  1113. private bool _IsLogin = false;
  1114. public bool IsLogin
  1115. {
  1116. get { return _IsLogin; }
  1117. set { _IsLogin = value; NotifyOfPropertyChange("IsLogin"); }
  1118. }
  1119. private List<Role> roles;
  1120. public List<Role> Roles
  1121. {
  1122. get { return this.roles; }
  1123. set { this.roles = value; this.RaisePropertyChangedEventImmediately("Roles"); }
  1124. }
  1125. private ICommand menuItemClickCommand;
  1126. public ICommand MenuItemClickCommand
  1127. {
  1128. get
  1129. {
  1130. if (this.menuItemClickCommand == null)
  1131. this.menuItemClickCommand = new BaseCommand<AppMenu>((AppMenu menuViewItem) => this.SwitchMenuItem(menuViewItem));
  1132. return this.menuItemClickCommand;
  1133. }
  1134. }
  1135. private ICommand mainmenuItemClickCommand;
  1136. public ICommand MainMenuItemClickCommand
  1137. {
  1138. get
  1139. {
  1140. if (this.mainmenuItemClickCommand == null)
  1141. this.mainmenuItemClickCommand = new BaseCommand<AppMenu>((AppMenu menuViewItem) => this.MainSwitchMenuItem(menuViewItem));
  1142. return this.mainmenuItemClickCommand;
  1143. }
  1144. }
  1145. public List<AppMenu> MenuItems
  1146. {
  1147. get { return this.menuItems; }
  1148. set { this.menuItems = value; this.NotifyOfPropertyChange("MenuItems"); }
  1149. }
  1150. public List<AppMenu> SubMenuItems
  1151. {
  1152. get { return this.subMenuItems; }
  1153. set { this.subMenuItems = value; this.NotifyOfPropertyChange("SubMenuItems"); }
  1154. }
  1155. public ObservableCollection<AppMenu> HistoryMenus
  1156. {
  1157. get { return this.historyItems; }
  1158. set { this.historyItems = value; this.NotifyOfPropertyChange("HistoryMenus"); }
  1159. }
  1160. public string Context
  1161. {
  1162. get { return this.context; }
  1163. set { this.context = value; this.NotifyOfPropertyChange("Context"); }
  1164. }
  1165. public BaseModel CurrentViewModel { get; private set; }
  1166. public UserContext User { get { return BaseApp.Instance.UserContext; } }
  1167. private AppMenu _currentMenuItem;
  1168. private List<AppMenu> menuItems;
  1169. private List<AppMenu> subMenuItems;
  1170. private ObservableCollection<AppMenu> historyItems;
  1171. private string context;
  1172. private MainView _view;
  1173. private Dictionary<Type, BaseModel> _models;
  1174. }
  1175. }