DynamicMenuBar.cs 59 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403
  1. using System;
  2. using System.Collections.ObjectModel;
  3. using System.ComponentModel;
  4. using System.Reflection;
  5. using System.Runtime.CompilerServices;
  6. using System.Text;
  7. using Terminal.Gui;
  8. namespace UICatalog.Scenarios;
  9. [ScenarioMetadata ("Dynamic MenuBar", "Demonstrates how to change a MenuBar dynamically.")]
  10. [ScenarioCategory ("Top Level Windows")]
  11. [ScenarioCategory ("Menus")]
  12. public class DynamicMenuBar : Scenario
  13. {
  14. public override void Main ()
  15. {
  16. // Init
  17. Application.Init ();
  18. // Setup - Create a top-level application window and configure it.
  19. DynamicMenuBarSample appWindow = new ()
  20. {
  21. Title = GetQuitKeyAndName ()
  22. };
  23. // Run - Start the application.
  24. Application.Run (appWindow);
  25. appWindow.Dispose ();
  26. // Shutdown - Calling Application.Shutdown is required.
  27. Application.Shutdown ();
  28. }
  29. public class Binding
  30. {
  31. private readonly PropertyInfo _sourceBindingProperty;
  32. private readonly object _sourceDataContext;
  33. private readonly IValueConverter _valueConverter;
  34. public Binding (
  35. View source,
  36. string sourcePropertyName,
  37. View target,
  38. string targetPropertyName,
  39. IValueConverter valueConverter = null
  40. )
  41. {
  42. Target = target;
  43. Source = source;
  44. SourcePropertyName = sourcePropertyName;
  45. TargetPropertyName = targetPropertyName;
  46. _sourceDataContext = Source.GetType ().GetProperty ("DataContext").GetValue (Source);
  47. _sourceBindingProperty = _sourceDataContext.GetType ().GetProperty (SourcePropertyName);
  48. _valueConverter = valueConverter;
  49. UpdateTarget ();
  50. var notifier = (INotifyPropertyChanged)_sourceDataContext;
  51. if (notifier != null)
  52. {
  53. notifier.PropertyChanged += (s, e) =>
  54. {
  55. if (e.PropertyName == SourcePropertyName)
  56. {
  57. UpdateTarget ();
  58. }
  59. };
  60. }
  61. }
  62. public View Source { get; }
  63. public string SourcePropertyName { get; }
  64. public View Target { get; }
  65. public string TargetPropertyName { get; }
  66. private void UpdateTarget ()
  67. {
  68. try
  69. {
  70. object sourceValue = _sourceBindingProperty.GetValue (_sourceDataContext);
  71. if (sourceValue == null)
  72. {
  73. return;
  74. }
  75. object finalValue = _valueConverter?.Convert (sourceValue) ?? sourceValue;
  76. PropertyInfo targetProperty = Target.GetType ().GetProperty (TargetPropertyName);
  77. targetProperty.SetValue (Target, finalValue);
  78. }
  79. catch (Exception ex)
  80. {
  81. MessageBox.ErrorQuery ("Binding Error", $"Binding failed: {ex}.", "Ok");
  82. }
  83. }
  84. }
  85. public class DynamicMenuBarDetails : FrameView
  86. {
  87. private bool _hasParent;
  88. private MenuItem _menuItem;
  89. public DynamicMenuBarDetails (MenuItem menuItem = null, bool hasParent = false) : this ()
  90. {
  91. _menuItem = menuItem;
  92. _hasParent = hasParent;
  93. Title = menuItem == null ? "Adding New Menu." : "Editing Menu.";
  94. }
  95. public DynamicMenuBarDetails ()
  96. {
  97. var lblTitle = new Label { Y = 1, Text = "Title:" };
  98. Add (lblTitle);
  99. TextTitle = new () { X = Pos.Right (lblTitle) + 2, Y = Pos.Top (lblTitle), Width = Dim.Fill () };
  100. Add (TextTitle);
  101. var lblHelp = new Label { X = Pos.Left (lblTitle), Y = Pos.Bottom (lblTitle) + 1, Text = "Help:" };
  102. Add (lblHelp);
  103. TextHelp = new () { X = Pos.Left (TextTitle), Y = Pos.Top (lblHelp), Width = Dim.Fill () };
  104. Add (TextHelp);
  105. var lblAction = new Label { X = Pos.Left (lblTitle), Y = Pos.Bottom (lblHelp) + 1, Text = "Action:" };
  106. Add (lblAction);
  107. TextAction = new ()
  108. {
  109. X = Pos.Left (TextTitle), Y = Pos.Top (lblAction), Width = Dim.Fill (), Height = 5
  110. };
  111. Add (TextAction);
  112. var lblHotKey = new Label { X = Pos.Left (lblTitle), Y = Pos.Bottom (lblAction) + 5, Text = "HotKey:" };
  113. Add (lblHotKey);
  114. TextHotKey = new ()
  115. {
  116. X = Pos.Left (TextTitle), Y = Pos.Bottom (lblAction) + 5, Width = 2, ReadOnly = true
  117. };
  118. TextHotKey.TextChanging += (s, e) =>
  119. {
  120. if (!string.IsNullOrEmpty (e.NewValue) && char.IsLower (e.NewValue [0]))
  121. {
  122. e.NewValue = e.NewValue.ToUpper ();
  123. }
  124. };
  125. TextHotKey.TextChanged += (s, _) => TextHotKey.SelectAll ();
  126. TextHotKey.SelectAll ();
  127. Add (TextHotKey);
  128. CkbIsTopLevel = new ()
  129. {
  130. X = Pos.Left (lblTitle), Y = Pos.Bottom (lblHotKey) + 1, Text = "IsTopLevel"
  131. };
  132. Add (CkbIsTopLevel);
  133. CkbSubMenu = new ()
  134. {
  135. X = Pos.Left (lblTitle),
  136. Y = Pos.Bottom (CkbIsTopLevel),
  137. CheckedState = (_menuItem == null ? !_hasParent : HasSubMenus (_menuItem)) ? CheckState.Checked : CheckState.UnChecked,
  138. Text = "Has sub-menus"
  139. };
  140. Add (CkbSubMenu);
  141. CkbNullCheck = new ()
  142. {
  143. X = Pos.Left (lblTitle), Y = Pos.Bottom (CkbSubMenu), Text = "Allow null checked"
  144. };
  145. Add (CkbNullCheck);
  146. var rChkLabels = new [] { "NoCheck", "Checked", "Radio" };
  147. RbChkStyle = new ()
  148. {
  149. X = Pos.Left (lblTitle), Y = Pos.Bottom (CkbSubMenu) + 1, RadioLabels = rChkLabels
  150. };
  151. Add (RbChkStyle);
  152. var lblShortcut = new Label
  153. {
  154. X = Pos.Right (CkbSubMenu) + 10, Y = Pos.Top (CkbSubMenu), Text = "Shortcut:"
  155. };
  156. Add (lblShortcut);
  157. TextShortcutKey = new ()
  158. {
  159. X = Pos.X (lblShortcut), Y = Pos.Bottom (lblShortcut), Width = Dim.Fill (), ReadOnly = true
  160. };
  161. TextShortcutKey.KeyDown += (s, e) =>
  162. {
  163. TextShortcutKey.Text = e.ToString ();
  164. };
  165. Add (TextShortcutKey);
  166. var btnShortcut = new Button
  167. {
  168. X = Pos.X (lblShortcut), Y = Pos.Bottom (TextShortcutKey) + 1, Text = "Clear Shortcut"
  169. };
  170. btnShortcut.Accept += (s, e) => { TextShortcutKey.Text = ""; };
  171. Add (btnShortcut);
  172. CkbIsTopLevel.CheckedStateChanging += (s, e) =>
  173. {
  174. if ((_menuItem != null && _menuItem.Parent != null && e.NewValue == CheckState.Checked)
  175. || (_menuItem == null && _hasParent && e.NewValue == CheckState.Checked))
  176. {
  177. MessageBox.ErrorQuery (
  178. "Invalid IsTopLevel",
  179. "Only menu bar can have top level menu item!",
  180. "Ok"
  181. );
  182. e.Cancel = true;
  183. return;
  184. }
  185. if (e.NewValue == CheckState.Checked)
  186. {
  187. CkbSubMenu.CheckedState = CheckState.UnChecked;
  188. CkbSubMenu.SetNeedsDisplay ();
  189. TextHelp.Enabled = true;
  190. TextAction.Enabled = true;
  191. TextShortcutKey.Enabled = true;
  192. }
  193. else
  194. {
  195. if ((_menuItem == null && !_hasParent) || _menuItem.Parent == null)
  196. {
  197. CkbSubMenu.CheckedState = CheckState.Checked;
  198. CkbSubMenu.SetNeedsDisplay ();
  199. TextShortcutKey.Enabled = false;
  200. }
  201. TextHelp.Text = "";
  202. TextHelp.Enabled = false;
  203. TextAction.Text = "";
  204. TextShortcutKey.Enabled =
  205. e.NewValue == CheckState.Checked && CkbSubMenu.CheckedState == CheckState.UnChecked;
  206. }
  207. };
  208. CkbSubMenu.CheckedStateChanging += (s, e) =>
  209. {
  210. if (e.NewValue == CheckState.Checked)
  211. {
  212. CkbIsTopLevel.CheckedState = CheckState.UnChecked;
  213. CkbIsTopLevel.SetNeedsDisplay ();
  214. TextHelp.Text = "";
  215. TextHelp.Enabled = false;
  216. TextAction.Text = "";
  217. TextAction.Enabled = false;
  218. TextShortcutKey.Text = "";
  219. TextShortcutKey.Enabled = false;
  220. }
  221. else
  222. {
  223. if (!_hasParent)
  224. {
  225. CkbIsTopLevel.CheckedState = CheckState.Checked;
  226. CkbIsTopLevel.SetNeedsDisplay ();
  227. TextShortcutKey.Enabled = true;
  228. }
  229. TextHelp.Enabled = true;
  230. TextAction.Enabled = true;
  231. if (_hasParent)
  232. {
  233. TextShortcutKey.Enabled = CkbIsTopLevel.CheckedState == CheckState.UnChecked
  234. && e.NewValue == CheckState.UnChecked;
  235. }
  236. }
  237. };
  238. CkbNullCheck.CheckedStateChanging += (s, e) =>
  239. {
  240. if (_menuItem != null)
  241. {
  242. _menuItem.AllowNullChecked = e.NewValue == CheckState.Checked;
  243. }
  244. };
  245. //Add (_frmMenuDetails);
  246. }
  247. public CheckBox CkbIsTopLevel { get; }
  248. public CheckBox CkbNullCheck { get; }
  249. public CheckBox CkbSubMenu { get; }
  250. public RadioGroup RbChkStyle { get; }
  251. public TextView TextAction { get; }
  252. public TextField TextHelp { get; }
  253. public TextField TextHotKey { get; }
  254. public TextField TextShortcutKey { get; }
  255. public TextField TextTitle { get; }
  256. public Action CreateAction (MenuItem menuItem, DynamicMenuItem item)
  257. {
  258. switch (menuItem.CheckType)
  259. {
  260. case MenuItemCheckStyle.NoCheck:
  261. return () => MessageBox.ErrorQuery (item.Title, item.Action, "Ok");
  262. case MenuItemCheckStyle.Checked:
  263. return menuItem.ToggleChecked;
  264. case MenuItemCheckStyle.Radio:
  265. break;
  266. }
  267. return () =>
  268. {
  269. menuItem.Checked = true;
  270. var parent = menuItem?.Parent as MenuBarItem;
  271. if (parent != null)
  272. {
  273. MenuItem [] childrens = parent.Children;
  274. for (var i = 0; i < childrens.Length; i++)
  275. {
  276. MenuItem child = childrens [i];
  277. if (child != menuItem)
  278. {
  279. child.Checked = false;
  280. }
  281. }
  282. }
  283. };
  284. }
  285. public void EditMenuBarItem (MenuItem menuItem)
  286. {
  287. if (menuItem == null)
  288. {
  289. _hasParent = false;
  290. Enabled = false;
  291. CleanEditMenuBarItem ();
  292. return;
  293. }
  294. _hasParent = menuItem.Parent != null;
  295. Enabled = true;
  296. _menuItem = menuItem;
  297. TextTitle.Text = menuItem?.Title ?? "";
  298. TextHelp.Text = menuItem?.Help ?? "";
  299. TextAction.Text = menuItem.Action != null
  300. ? GetTargetAction (menuItem.Action)
  301. : string.Empty;
  302. TextHotKey.Text = menuItem?.HotKey != Key.Empty ? menuItem.HotKey.ToString () : "";
  303. CkbIsTopLevel.CheckedState = IsTopLevel (menuItem) ? CheckState.Checked : CheckState.UnChecked;
  304. CkbSubMenu.CheckedState = HasSubMenus (menuItem) ? CheckState.Checked : CheckState.UnChecked;
  305. CkbNullCheck.CheckedState = menuItem.AllowNullChecked ? CheckState.Checked : CheckState.UnChecked;
  306. TextHelp.Enabled = CkbSubMenu.CheckedState == CheckState.UnChecked;
  307. TextAction.Enabled = CkbSubMenu.CheckedState == CheckState.UnChecked;
  308. RbChkStyle.SelectedItem = (int)(menuItem?.CheckType ?? MenuItemCheckStyle.NoCheck);
  309. TextShortcutKey.Text = menuItem?.ShortcutTag ?? "";
  310. TextShortcutKey.Enabled = CkbIsTopLevel.CheckedState == CheckState.Checked && CkbSubMenu.CheckedState == CheckState.UnChecked
  311. || CkbIsTopLevel.CheckedState == CheckState.UnChecked && CkbSubMenu.CheckedState == CheckState.UnChecked;
  312. }
  313. public DynamicMenuItem EnterMenuItem ()
  314. {
  315. var valid = false;
  316. if (_menuItem == null)
  317. {
  318. var m = new DynamicMenuItem ();
  319. TextTitle.Text = m.Title;
  320. TextHelp.Text = m.Help;
  321. TextAction.Text = m.Action;
  322. TextHotKey.Text = m.HotKey ?? string.Empty;
  323. CkbIsTopLevel.CheckedState = CheckState.UnChecked;
  324. CkbSubMenu.CheckedState = !_hasParent ? CheckState.Checked : CheckState.UnChecked;
  325. CkbNullCheck.CheckedState = CheckState.UnChecked;
  326. TextHelp.Enabled = _hasParent;
  327. TextAction.Enabled = _hasParent;
  328. TextShortcutKey.Enabled = _hasParent;
  329. }
  330. else
  331. {
  332. EditMenuBarItem (_menuItem);
  333. }
  334. var btnOk = new Button { IsDefault = true, Text = "Ok" };
  335. btnOk.Accept += (s, e) =>
  336. {
  337. if (string.IsNullOrEmpty (TextTitle.Text))
  338. {
  339. MessageBox.ErrorQuery ("Invalid title", "Must enter a valid title!.", "Ok");
  340. }
  341. else
  342. {
  343. valid = true;
  344. Application.RequestStop ();
  345. }
  346. };
  347. var btnCancel = new Button { Text = "Cancel" };
  348. btnCancel.Accept += (s, e) =>
  349. {
  350. TextTitle.Text = string.Empty;
  351. Application.RequestStop ();
  352. };
  353. var dialog = new Dialog
  354. { Title = "Enter the menu details.", Buttons = [btnOk, btnCancel], Height = Dim.Auto (DimAutoStyle.Content, 22, Driver.Rows) };
  355. Width = Dim.Fill ();
  356. Height = Dim.Fill () - 1;
  357. dialog.Add (this);
  358. TextTitle.SetFocus ();
  359. TextTitle.CursorPosition = TextTitle.Text.Length;
  360. Application.Run (dialog);
  361. dialog.Dispose ();
  362. if (valid)
  363. {
  364. return new ()
  365. {
  366. Title = TextTitle.Text,
  367. Help = TextHelp.Text,
  368. Action = TextAction.Text,
  369. HotKey = TextHotKey.Text,
  370. IsTopLevel = CkbIsTopLevel?.CheckedState == CheckState.Checked,
  371. HasSubMenu = CkbSubMenu?.CheckedState == CheckState.Checked,
  372. CheckStyle = RbChkStyle.SelectedItem == 0 ? MenuItemCheckStyle.NoCheck :
  373. RbChkStyle.SelectedItem == 1 ? MenuItemCheckStyle.Checked :
  374. MenuItemCheckStyle.Radio,
  375. ShortcutKey = TextShortcutKey.Text,
  376. AllowNullChecked = CkbNullCheck?.CheckedState == CheckState.Checked,
  377. };
  378. }
  379. return null;
  380. }
  381. public void UpdateParent (ref MenuItem menuItem)
  382. {
  383. var parent = menuItem.Parent as MenuBarItem;
  384. int idx = parent.GetChildrenIndex (menuItem);
  385. if (!(menuItem is MenuBarItem))
  386. {
  387. menuItem = new MenuBarItem (menuItem.Title, new MenuItem [] { }, menuItem.Parent);
  388. if (idx > -1)
  389. {
  390. parent.Children [idx] = menuItem;
  391. }
  392. }
  393. else
  394. {
  395. menuItem = new (
  396. menuItem.Title,
  397. menuItem.Help,
  398. CreateAction (menuItem, new ()),
  399. null,
  400. menuItem.Parent
  401. );
  402. if (idx > -1)
  403. {
  404. parent.Children [idx] = menuItem;
  405. }
  406. }
  407. }
  408. private void CleanEditMenuBarItem ()
  409. {
  410. TextTitle.Text = "";
  411. TextHelp.Text = "";
  412. TextAction.Text = "";
  413. TextHotKey.Text = "";
  414. CkbIsTopLevel.CheckedState = CheckState.UnChecked;
  415. CkbSubMenu.CheckedState = CheckState.UnChecked;
  416. RbChkStyle.SelectedItem = (int)MenuItemCheckStyle.NoCheck;
  417. TextShortcutKey.Text = "";
  418. }
  419. private string GetTargetAction (Action action)
  420. {
  421. object me = action.Target;
  422. if (me == null)
  423. {
  424. throw new ArgumentException ();
  425. }
  426. var v = new object ();
  427. foreach (FieldInfo field in me.GetType ().GetFields ())
  428. {
  429. if (field.Name == "item")
  430. {
  431. v = field.GetValue (me);
  432. }
  433. }
  434. return v == null || !(v is DynamicMenuItem item) ? string.Empty : item.Action;
  435. }
  436. private bool HasSubMenus (MenuItem menuItem)
  437. {
  438. var menuBarItem = menuItem as MenuBarItem;
  439. if (menuBarItem != null && menuBarItem.Children != null && (menuBarItem.Children.Length > 0 || menuBarItem.Action == null))
  440. {
  441. return true;
  442. }
  443. return false;
  444. }
  445. private bool IsTopLevel (MenuItem menuItem)
  446. {
  447. var topLevel = menuItem as MenuBarItem;
  448. if (topLevel != null && topLevel.Parent == null && (topLevel.Children == null || topLevel.Children.Length == 0) && topLevel.Action != null)
  449. {
  450. return true;
  451. }
  452. return false;
  453. }
  454. }
  455. public class DynamicMenuBarSample : Window
  456. {
  457. private readonly ListView _lstMenus;
  458. private MenuItem _currentEditMenuBarItem;
  459. private MenuItem _currentMenuBarItem;
  460. private int _currentSelectedMenuBar;
  461. private MenuBar _menuBar;
  462. public DynamicMenuBarSample ()
  463. {
  464. DataContext = new ();
  465. var frmDelimiter = new FrameView
  466. {
  467. X = Pos.Center (),
  468. Y = 3,
  469. Width = 25,
  470. Height = 4,
  471. Title = "Shortcut Delimiter:"
  472. };
  473. var txtDelimiter = new TextField
  474. {
  475. X = Pos.Center (), Width = 2, Text = Key.Separator.ToString ()
  476. };
  477. var frmMenu = new FrameView { Y = 7, Width = Dim.Percent (50), Height = Dim.Fill (), Title = "Menus:" };
  478. var btnAddMenuBar = new Button { Y = 1, Text = "Add a MenuBar" };
  479. frmMenu.Add (btnAddMenuBar);
  480. var btnMenuBarUp = new Button { X = Pos.Center (), Text = CM.Glyphs.UpArrow.ToString () };
  481. frmMenu.Add (btnMenuBarUp);
  482. var btnMenuBarDown = new Button { X = Pos.Center (), Y = Pos.Bottom (btnMenuBarUp), Text = CM.Glyphs.DownArrow.ToString () };
  483. frmMenu.Add (btnMenuBarDown);
  484. var btnRemoveMenuBar = new Button { Y = 1, Text = "Remove a MenuBar" };
  485. btnRemoveMenuBar.X = Pos.AnchorEnd (0) - (Pos.Right (btnRemoveMenuBar) - Pos.Left (btnRemoveMenuBar));
  486. frmMenu.Add (btnRemoveMenuBar);
  487. var btnPrevious = new Button
  488. {
  489. X = Pos.Left (btnAddMenuBar), Y = Pos.Top (btnAddMenuBar) + 2, Text = CM.Glyphs.LeftArrow.ToString ()
  490. };
  491. frmMenu.Add (btnPrevious);
  492. var btnAdd = new Button { Y = Pos.Top (btnPrevious) + 2, Text = " Add " };
  493. btnAdd.X = Pos.AnchorEnd ();
  494. frmMenu.Add (btnAdd);
  495. var btnNext = new Button { X = Pos.X (btnAdd), Y = Pos.Top (btnPrevious), Text = CM.Glyphs.RightArrow.ToString () };
  496. frmMenu.Add (btnNext);
  497. var lblMenuBar = new Label
  498. {
  499. ColorScheme = Colors.ColorSchemes ["Dialog"],
  500. TextAlignment = Alignment.Center,
  501. X = Pos.Right (btnPrevious) + 1,
  502. Y = Pos.Top (btnPrevious),
  503. Width = Dim.Fill () - Dim.Func (() => btnAdd.Frame.Width + 1),
  504. Height = 1
  505. };
  506. lblMenuBar.TextChanged += (s, e) =>
  507. {
  508. if (lblMenuBar.Text.Contains ("_"))
  509. {
  510. lblMenuBar.Text = lblMenuBar.Text.Replace ("_", "");
  511. }
  512. };
  513. frmMenu.Add (lblMenuBar);
  514. lblMenuBar.WantMousePositionReports = true;
  515. lblMenuBar.CanFocus = true;
  516. var lblParent = new Label
  517. {
  518. TextAlignment = Alignment.Center,
  519. X = Pos.Right (btnPrevious) + 1,
  520. Y = Pos.Top (btnPrevious) + 1,
  521. Width = Dim.Fill () - Dim.Width (btnAdd) - 1
  522. };
  523. frmMenu.Add (lblParent);
  524. var btnPreviowsParent = new Button
  525. {
  526. X = Pos.Left (btnAddMenuBar), Y = Pos.Top (btnPrevious) + 1, Text = ".."
  527. };
  528. frmMenu.Add (btnPreviowsParent);
  529. _lstMenus = new ()
  530. {
  531. ColorScheme = Colors.ColorSchemes ["Dialog"],
  532. X = Pos.Right (btnPrevious) + 1,
  533. Y = Pos.Top (btnPrevious) + 2,
  534. Width = lblMenuBar.Width,
  535. Height = Dim.Fill (),
  536. Source = new ListWrapper<DynamicMenuItemList> ([])
  537. };
  538. frmMenu.Add (_lstMenus);
  539. //lblMenuBar.TabIndex = btnPrevious.TabIndex + 1;
  540. //_lstMenus.TabIndex = lblMenuBar.TabIndex + 1;
  541. //btnNext.TabIndex = _lstMenus.TabIndex + 1;
  542. //btnAdd.TabIndex = btnNext.TabIndex + 1;
  543. var btnRemove = new Button { X = Pos.Left (btnAdd), Y = Pos.Top (btnAdd) + 1, Text = "Remove" };
  544. frmMenu.Add (btnRemove);
  545. var btnUp = new Button { X = Pos.Right (_lstMenus) + 2, Y = Pos.Top (btnRemove) + 2, Text = CM.Glyphs.UpArrow.ToString () };
  546. frmMenu.Add (btnUp);
  547. var btnDown = new Button { X = Pos.Right (_lstMenus) + 2, Y = Pos.Top (btnUp) + 1, Text = CM.Glyphs.DownArrow.ToString () };
  548. frmMenu.Add (btnDown);
  549. Add (frmMenu);
  550. var frmMenuDetails = new DynamicMenuBarDetails
  551. {
  552. X = Pos.Right (frmMenu),
  553. Y = Pos.Top (frmMenu),
  554. Width = Dim.Fill (),
  555. Height = Dim.Fill (2),
  556. Title = "Menu Details:"
  557. };
  558. Add (frmMenuDetails);
  559. btnMenuBarUp.Accept += (s, e) =>
  560. {
  561. int i = _currentSelectedMenuBar;
  562. MenuBarItem menuItem = _menuBar != null && _menuBar.Menus.Length > 0
  563. ? _menuBar.Menus [i]
  564. : null;
  565. if (menuItem != null)
  566. {
  567. MenuBarItem [] menus = _menuBar.Menus;
  568. if (i > 0)
  569. {
  570. menus [i] = menus [i - 1];
  571. menus [i - 1] = menuItem;
  572. _currentSelectedMenuBar = i - 1;
  573. _menuBar.SetNeedsDisplay ();
  574. }
  575. }
  576. };
  577. btnMenuBarDown.Accept += (s, e) =>
  578. {
  579. int i = _currentSelectedMenuBar;
  580. MenuBarItem menuItem = _menuBar != null && _menuBar.Menus.Length > 0
  581. ? _menuBar.Menus [i]
  582. : null;
  583. if (menuItem != null)
  584. {
  585. MenuBarItem [] menus = _menuBar.Menus;
  586. if (i < menus.Length - 1)
  587. {
  588. menus [i] = menus [i + 1];
  589. menus [i + 1] = menuItem;
  590. _currentSelectedMenuBar = i + 1;
  591. _menuBar.SetNeedsDisplay ();
  592. }
  593. }
  594. };
  595. btnUp.Accept += (s, e) =>
  596. {
  597. int i = _lstMenus.SelectedItem;
  598. MenuItem menuItem = DataContext.Menus.Count > 0 ? DataContext.Menus [i].MenuItem : null;
  599. if (menuItem != null)
  600. {
  601. MenuItem [] childrens = ((MenuBarItem)_currentMenuBarItem).Children;
  602. if (i > 0)
  603. {
  604. childrens [i] = childrens [i - 1];
  605. childrens [i - 1] = menuItem;
  606. DataContext.Menus [i] = DataContext.Menus [i - 1];
  607. DataContext.Menus [i - 1] =
  608. new () { Title = menuItem.Title, MenuItem = menuItem };
  609. _lstMenus.SelectedItem = i - 1;
  610. }
  611. }
  612. };
  613. btnDown.Accept += (s, e) =>
  614. {
  615. int i = _lstMenus.SelectedItem;
  616. MenuItem menuItem = DataContext.Menus.Count > 0 ? DataContext.Menus [i].MenuItem : null;
  617. if (menuItem != null)
  618. {
  619. MenuItem [] childrens = ((MenuBarItem)_currentMenuBarItem).Children;
  620. if (i < childrens.Length - 1)
  621. {
  622. childrens [i] = childrens [i + 1];
  623. childrens [i + 1] = menuItem;
  624. DataContext.Menus [i] = DataContext.Menus [i + 1];
  625. DataContext.Menus [i + 1] =
  626. new () { Title = menuItem.Title, MenuItem = menuItem };
  627. _lstMenus.SelectedItem = i + 1;
  628. }
  629. }
  630. };
  631. btnPreviowsParent.Accept += (s, e) =>
  632. {
  633. if (_currentMenuBarItem != null && _currentMenuBarItem.Parent != null)
  634. {
  635. MenuItem mi = _currentMenuBarItem;
  636. _currentMenuBarItem = _currentMenuBarItem.Parent as MenuBarItem;
  637. SetListViewSource (_currentMenuBarItem, true);
  638. int i = ((MenuBarItem)_currentMenuBarItem).GetChildrenIndex (mi);
  639. if (i > -1)
  640. {
  641. _lstMenus.SelectedItem = i;
  642. }
  643. if (_currentMenuBarItem.Parent != null)
  644. {
  645. DataContext.Parent = _currentMenuBarItem.Title;
  646. }
  647. else
  648. {
  649. DataContext.Parent = string.Empty;
  650. }
  651. }
  652. else
  653. {
  654. DataContext.Parent = string.Empty;
  655. }
  656. };
  657. var btnOk = new Button { X = Pos.Right (frmMenu) + 20, Y = Pos.Bottom (frmMenuDetails), Text = "Ok" };
  658. Add (btnOk);
  659. var btnCancel = new Button { X = Pos.Right (btnOk) + 3, Y = Pos.Top (btnOk), Text = "Cancel" };
  660. btnCancel.Accept += (s, e) => { SetFrameDetails (_currentEditMenuBarItem); };
  661. Add (btnCancel);
  662. txtDelimiter.TextChanging += (s, e) =>
  663. {
  664. if (!string.IsNullOrEmpty (e.NewValue))
  665. {
  666. Key.Separator = e.NewValue.ToRunes () [0];
  667. }
  668. else
  669. {
  670. e.Cancel = true;
  671. txtDelimiter.SelectAll ();
  672. }
  673. };
  674. txtDelimiter.TextChanged += (s, _) =>
  675. {
  676. txtDelimiter.SelectAll ();
  677. SetFrameDetails ();
  678. };
  679. frmDelimiter.Add (txtDelimiter);
  680. txtDelimiter.SelectAll ();
  681. Add (frmDelimiter);
  682. _lstMenus.SelectedItemChanged += (s, e) => { SetFrameDetails (); };
  683. btnOk.Accept += (s, e) =>
  684. {
  685. if (string.IsNullOrEmpty (frmMenuDetails.TextTitle.Text) && _currentEditMenuBarItem != null)
  686. {
  687. MessageBox.ErrorQuery ("Invalid title", "Must enter a valid title!.", "Ok");
  688. }
  689. else if (_currentEditMenuBarItem != null)
  690. {
  691. var menuItem = new DynamicMenuItem
  692. {
  693. Title = frmMenuDetails.TextTitle.Text,
  694. Help = frmMenuDetails.TextHelp.Text,
  695. Action = frmMenuDetails.TextAction.Text,
  696. HotKey = frmMenuDetails.TextHotKey.Text,
  697. IsTopLevel = frmMenuDetails.CkbIsTopLevel?.CheckedState == CheckState.Checked,
  698. HasSubMenu = frmMenuDetails.CkbSubMenu?.CheckedState == CheckState.Checked,
  699. CheckStyle = frmMenuDetails.RbChkStyle.SelectedItem == 0
  700. ? MenuItemCheckStyle.NoCheck
  701. : frmMenuDetails.RbChkStyle.SelectedItem == 1
  702. ? MenuItemCheckStyle.Checked
  703. : MenuItemCheckStyle.Radio,
  704. ShortcutKey = frmMenuDetails.TextShortcutKey.Text
  705. };
  706. UpdateMenuItem (_currentEditMenuBarItem, menuItem, _lstMenus.SelectedItem);
  707. }
  708. };
  709. btnAdd.Accept += (s, e) =>
  710. {
  711. if (MenuBar == null)
  712. {
  713. MessageBox.ErrorQuery ("Menu Bar Error", "Must add a MenuBar first!", "Ok");
  714. btnAddMenuBar.SetFocus ();
  715. return;
  716. }
  717. var frameDetails = new DynamicMenuBarDetails (null, _currentMenuBarItem != null);
  718. DynamicMenuItem item = frameDetails.EnterMenuItem ();
  719. if (item == null)
  720. {
  721. return;
  722. }
  723. if (_currentMenuBarItem is not MenuBarItem)
  724. {
  725. var parent = _currentMenuBarItem.Parent as MenuBarItem;
  726. int idx = parent.GetChildrenIndex (_currentMenuBarItem);
  727. _currentMenuBarItem = new MenuBarItem (
  728. _currentMenuBarItem.Title,
  729. new MenuItem [] { },
  730. _currentMenuBarItem.Parent
  731. );
  732. _currentMenuBarItem.CheckType = item.CheckStyle;
  733. parent.Children [idx] = _currentMenuBarItem;
  734. }
  735. else
  736. {
  737. MenuItem newMenu = CreateNewMenu (item, _currentMenuBarItem);
  738. var menuBarItem = _currentMenuBarItem as MenuBarItem;
  739. menuBarItem.AddMenuBarItem (newMenu);
  740. DataContext.Menus.Add (new () { Title = newMenu.Title, MenuItem = newMenu });
  741. _lstMenus.MoveDown ();
  742. }
  743. };
  744. btnRemove.Accept += (s, e) =>
  745. {
  746. MenuItem menuItem = (DataContext.Menus.Count > 0 && _lstMenus.SelectedItem > -1
  747. ? DataContext.Menus [_lstMenus.SelectedItem].MenuItem
  748. : _currentEditMenuBarItem);
  749. if (menuItem != null)
  750. {
  751. menuItem.RemoveMenuItem ();
  752. if (_currentEditMenuBarItem == menuItem)
  753. {
  754. _currentEditMenuBarItem = null;
  755. if (menuItem.Parent is null)
  756. {
  757. _currentSelectedMenuBar = Math.Max (Math.Min (_currentSelectedMenuBar, _menuBar.Menus.Length - 1), 0);
  758. }
  759. SelectCurrentMenuBarItem ();
  760. }
  761. if (_lstMenus.SelectedItem > -1)
  762. {
  763. DataContext.Menus?.RemoveAt (_lstMenus.SelectedItem);
  764. }
  765. if (_lstMenus.Source.Count > 0 && _lstMenus.SelectedItem > _lstMenus.Source.Count - 1)
  766. {
  767. _lstMenus.SelectedItem = _lstMenus.Source.Count - 1;
  768. }
  769. _lstMenus.SetNeedsDisplay ();
  770. SetFrameDetails ();
  771. }
  772. };
  773. _lstMenus.OpenSelectedItem += (s, e) =>
  774. {
  775. _currentMenuBarItem = DataContext.Menus [e.Item].MenuItem;
  776. if (!(_currentMenuBarItem is MenuBarItem))
  777. {
  778. MessageBox.ErrorQuery ("Menu Open Error", "Must allows sub menus first!", "Ok");
  779. return;
  780. }
  781. DataContext.Parent = _currentMenuBarItem.Title;
  782. DataContext.Menus = new ();
  783. SetListViewSource (_currentMenuBarItem, true);
  784. MenuItem menuBarItem = DataContext.Menus.Count > 0 ? DataContext.Menus [0].MenuItem : null;
  785. SetFrameDetails (menuBarItem);
  786. };
  787. _lstMenus.HasFocusChanging += (s, e) =>
  788. {
  789. MenuItem menuBarItem = _lstMenus.SelectedItem > -1 && DataContext.Menus.Count > 0
  790. ? DataContext.Menus [_lstMenus.SelectedItem].MenuItem
  791. : null;
  792. SetFrameDetails (menuBarItem);
  793. };
  794. btnNext.Accept += (s, e) =>
  795. {
  796. if (_menuBar != null && _currentSelectedMenuBar + 1 < _menuBar.Menus.Length)
  797. {
  798. _currentSelectedMenuBar++;
  799. }
  800. SelectCurrentMenuBarItem ();
  801. };
  802. btnPrevious.Accept += (s, e) =>
  803. {
  804. if (_currentSelectedMenuBar - 1 > -1)
  805. {
  806. _currentSelectedMenuBar--;
  807. }
  808. SelectCurrentMenuBarItem ();
  809. };
  810. lblMenuBar.HasFocusChanging += (s, e) =>
  811. {
  812. if (_menuBar?.Menus != null)
  813. {
  814. _currentMenuBarItem = _menuBar.Menus [_currentSelectedMenuBar];
  815. SetFrameDetails (_menuBar.Menus [_currentSelectedMenuBar]);
  816. }
  817. };
  818. btnAddMenuBar.Accept += (s, e) =>
  819. {
  820. var frameDetails = new DynamicMenuBarDetails (null);
  821. DynamicMenuItem item = frameDetails.EnterMenuItem ();
  822. if (item == null)
  823. {
  824. return;
  825. }
  826. if (MenuBar == null)
  827. {
  828. _menuBar = new ();
  829. Add (_menuBar);
  830. }
  831. var newMenu = CreateNewMenu (item) as MenuBarItem;
  832. newMenu.AddMenuBarItem ();
  833. _currentMenuBarItem = newMenu;
  834. _currentMenuBarItem.CheckType = item.CheckStyle;
  835. if (Key.TryParse (item.ShortcutKey, out Key key))
  836. {
  837. _currentMenuBarItem.ShortcutKey = key;
  838. }
  839. _currentSelectedMenuBar = _menuBar.Menus.Length - 1;
  840. _menuBar.Menus [_currentSelectedMenuBar] = newMenu;
  841. lblMenuBar.Text = newMenu.Title;
  842. SetListViewSource (_currentMenuBarItem, true);
  843. SetFrameDetails (_menuBar.Menus [_currentSelectedMenuBar]);
  844. _menuBar.SetNeedsDisplay ();
  845. };
  846. btnRemoveMenuBar.Accept += (s, e) =>
  847. {
  848. if (_menuBar == null || _menuBar.Menus.Length == 0)
  849. {
  850. return;
  851. }
  852. if (_menuBar != null && _menuBar.Menus.Length > 0)
  853. {
  854. _currentMenuBarItem.RemoveMenuItem ();
  855. if (_currentSelectedMenuBar - 1 >= 0 && _menuBar.Menus.Length > 0)
  856. {
  857. _currentSelectedMenuBar--;
  858. }
  859. _currentMenuBarItem = _menuBar.Menus?.Length > 0
  860. ? _menuBar.Menus [_currentSelectedMenuBar]
  861. : null;
  862. }
  863. if (MenuBar != null && _currentMenuBarItem == null && _menuBar.Menus.Length == 0)
  864. {
  865. Remove (_menuBar);
  866. _menuBar.Dispose ();
  867. _menuBar = null;
  868. DataContext.Menus = new ();
  869. _currentMenuBarItem = null;
  870. _currentSelectedMenuBar = -1;
  871. lblMenuBar.Text = string.Empty;
  872. }
  873. else
  874. {
  875. lblMenuBar.Text = _menuBar.Menus [_currentSelectedMenuBar].Title;
  876. }
  877. SetListViewSource (_currentMenuBarItem, true);
  878. SetFrameDetails ();
  879. };
  880. SetFrameDetails ();
  881. var ustringConverter = new UStringValueConverter ();
  882. ListWrapperConverter<DynamicMenuItemList> listWrapperConverter = new ListWrapperConverter<DynamicMenuItemList> ();
  883. var bdgMenuBar = new Binding (this, "MenuBar", lblMenuBar, "Text", ustringConverter);
  884. var bdgParent = new Binding (this, "Parent", lblParent, "Text", ustringConverter);
  885. var bdgMenus = new Binding (this, "Menus", _lstMenus, "Source", listWrapperConverter);
  886. void SetFrameDetails (MenuItem menuBarItem = null)
  887. {
  888. MenuItem menuItem;
  889. if (menuBarItem == null)
  890. {
  891. menuItem = _lstMenus.SelectedItem > -1 && DataContext.Menus.Count > 0
  892. ? DataContext.Menus [_lstMenus.SelectedItem].MenuItem
  893. : _currentEditMenuBarItem;
  894. }
  895. else
  896. {
  897. menuItem = menuBarItem;
  898. }
  899. _currentEditMenuBarItem = menuItem;
  900. frmMenuDetails.EditMenuBarItem (menuItem);
  901. bool f = btnOk.Enabled == frmMenuDetails.Enabled;
  902. if (!f)
  903. {
  904. btnOk.Enabled = frmMenuDetails.Enabled;
  905. btnCancel.Enabled = frmMenuDetails.Enabled;
  906. }
  907. }
  908. void SelectCurrentMenuBarItem ()
  909. {
  910. MenuBarItem menuBarItem = null;
  911. if (_menuBar?.Menus is { Length: > 0 })
  912. {
  913. menuBarItem = _menuBar.Menus [_currentSelectedMenuBar];
  914. lblMenuBar.Text = menuBarItem.Title;
  915. }
  916. SetFrameDetails (menuBarItem);
  917. _currentMenuBarItem = menuBarItem;
  918. DataContext.Menus = new ();
  919. SetListViewSource (_currentMenuBarItem, true);
  920. lblParent.Text = string.Empty;
  921. if (_currentMenuBarItem is null)
  922. {
  923. lblMenuBar.Text = string.Empty;
  924. }
  925. }
  926. void SetListViewSource (MenuItem currentMenuBarItem, bool fill = false)
  927. {
  928. DataContext.Menus = [];
  929. var menuBarItem = currentMenuBarItem as MenuBarItem;
  930. if (menuBarItem != null && menuBarItem?.Children == null)
  931. {
  932. return;
  933. }
  934. if (!fill)
  935. {
  936. return;
  937. }
  938. if (menuBarItem != null)
  939. {
  940. foreach (MenuItem child in menuBarItem?.Children)
  941. {
  942. var m = new DynamicMenuItemList { Title = child.Title, MenuItem = child };
  943. DataContext.Menus.Add (m);
  944. }
  945. }
  946. }
  947. MenuItem CreateNewMenu (DynamicMenuItem item, MenuItem parent = null)
  948. {
  949. MenuItem newMenu;
  950. if (item.HasSubMenu)
  951. {
  952. newMenu = new MenuBarItem (item.Title, new MenuItem [] { }, parent);
  953. }
  954. else if (parent != null)
  955. {
  956. newMenu = new (item.Title, item.Help, null, null, parent);
  957. newMenu.CheckType = item.CheckStyle;
  958. newMenu.Action = frmMenuDetails.CreateAction (newMenu, item);
  959. if (Key.TryParse (item.ShortcutKey, out Key key))
  960. {
  961. newMenu.ShortcutKey = key;
  962. }
  963. newMenu.AllowNullChecked = item.AllowNullChecked;
  964. }
  965. else if (item.IsTopLevel)
  966. {
  967. newMenu = new MenuBarItem (item.Title, item.Help, null);
  968. newMenu.Action = frmMenuDetails.CreateAction (newMenu, item);
  969. if (Key.TryParse (item.ShortcutKey, out Key key))
  970. {
  971. newMenu.ShortcutKey = key;
  972. }
  973. }
  974. else
  975. {
  976. newMenu = new MenuBarItem (item.Title, item.Help, null);
  977. ((MenuBarItem)newMenu).Children [0].Action =
  978. frmMenuDetails.CreateAction (newMenu, item);
  979. if (Key.TryParse (item.ShortcutKey, out Key key))
  980. {
  981. ((MenuBarItem)newMenu).Children [0].ShortcutKey = key;
  982. }
  983. }
  984. return newMenu;
  985. }
  986. void UpdateMenuItem (MenuItem currentEditMenuBarItem, DynamicMenuItem menuItem, int index)
  987. {
  988. currentEditMenuBarItem.Title = menuItem.Title;
  989. currentEditMenuBarItem.Help = menuItem.Help;
  990. currentEditMenuBarItem.CheckType = menuItem.CheckStyle;
  991. if (currentEditMenuBarItem.Parent is MenuBarItem parent
  992. && parent.Children.Length == 1
  993. && currentEditMenuBarItem.CheckType == MenuItemCheckStyle.Radio)
  994. {
  995. currentEditMenuBarItem.Checked = true;
  996. }
  997. if (menuItem.IsTopLevel && currentEditMenuBarItem is MenuBarItem)
  998. {
  999. ((MenuBarItem)currentEditMenuBarItem).Children = null;
  1000. currentEditMenuBarItem.Action =
  1001. frmMenuDetails.CreateAction (currentEditMenuBarItem, menuItem);
  1002. if (Key.TryParse (menuItem.ShortcutKey, out Key key))
  1003. {
  1004. currentEditMenuBarItem.ShortcutKey = key;
  1005. }
  1006. SetListViewSource (currentEditMenuBarItem, true);
  1007. }
  1008. else if (menuItem.HasSubMenu)
  1009. {
  1010. currentEditMenuBarItem.Action = null;
  1011. if (currentEditMenuBarItem is MenuBarItem && ((MenuBarItem)currentEditMenuBarItem).Children == null)
  1012. {
  1013. ((MenuBarItem)currentEditMenuBarItem).Children = new MenuItem [] { };
  1014. }
  1015. else if (currentEditMenuBarItem.Parent != null)
  1016. {
  1017. frmMenuDetails.UpdateParent (ref currentEditMenuBarItem);
  1018. }
  1019. else
  1020. {
  1021. currentEditMenuBarItem =
  1022. new MenuBarItem (
  1023. currentEditMenuBarItem.Title,
  1024. new MenuItem [] { },
  1025. currentEditMenuBarItem.Parent
  1026. );
  1027. }
  1028. SetListViewSource (currentEditMenuBarItem, true);
  1029. }
  1030. else if (currentEditMenuBarItem is MenuBarItem && currentEditMenuBarItem.Parent != null)
  1031. {
  1032. frmMenuDetails.UpdateParent (ref currentEditMenuBarItem);
  1033. currentEditMenuBarItem = new (
  1034. menuItem.Title,
  1035. menuItem.Help,
  1036. frmMenuDetails.CreateAction (currentEditMenuBarItem, menuItem),
  1037. null,
  1038. currentEditMenuBarItem.Parent
  1039. );
  1040. }
  1041. else
  1042. {
  1043. if (currentEditMenuBarItem is MenuBarItem)
  1044. {
  1045. ((MenuBarItem)currentEditMenuBarItem).Children = null;
  1046. DataContext.Menus = new ();
  1047. }
  1048. currentEditMenuBarItem.Action =
  1049. frmMenuDetails.CreateAction (currentEditMenuBarItem, menuItem);
  1050. if (Key.TryParse (menuItem.ShortcutKey, out Key key))
  1051. {
  1052. currentEditMenuBarItem.ShortcutKey = key;
  1053. }
  1054. }
  1055. if (currentEditMenuBarItem.Parent == null)
  1056. {
  1057. DataContext.MenuBar = currentEditMenuBarItem.Title;
  1058. }
  1059. else
  1060. {
  1061. if (DataContext.Menus.Count == 0)
  1062. {
  1063. DataContext.Menus.Add (
  1064. new ()
  1065. {
  1066. Title = currentEditMenuBarItem.Title, MenuItem = currentEditMenuBarItem
  1067. }
  1068. );
  1069. }
  1070. DataContext.Menus [index] =
  1071. new ()
  1072. {
  1073. Title = currentEditMenuBarItem.Title, MenuItem = currentEditMenuBarItem
  1074. };
  1075. }
  1076. currentEditMenuBarItem.CheckType = menuItem.CheckStyle;
  1077. SetFrameDetails (currentEditMenuBarItem);
  1078. }
  1079. //_frmMenuDetails.Initialized += (s, e) => _frmMenuDetails.Enabled = false;
  1080. }
  1081. public DynamicMenuItemModel DataContext { get; set; }
  1082. }
  1083. public class DynamicMenuItem
  1084. {
  1085. public string Action { get; set; } = string.Empty;
  1086. public bool AllowNullChecked { get; set; }
  1087. public MenuItemCheckStyle CheckStyle { get; set; }
  1088. public bool HasSubMenu { get; set; }
  1089. public string Help { get; set; } = string.Empty;
  1090. public bool IsTopLevel { get; set; }
  1091. public string HotKey { get; set; }
  1092. public string ShortcutKey { get; set; }
  1093. public string Title { get; set; } = "_New";
  1094. }
  1095. public class DynamicMenuItemList
  1096. {
  1097. public MenuItem MenuItem { get; set; }
  1098. public string Title { get; set; }
  1099. public override string ToString () { return $"{Title}, {MenuItem.HotKey}, {MenuItem.ShortcutKey} "; }
  1100. }
  1101. public class DynamicMenuItemModel : INotifyPropertyChanged
  1102. {
  1103. private string _menuBar;
  1104. private ObservableCollection<DynamicMenuItemList> _menus;
  1105. private string _parent;
  1106. public DynamicMenuItemModel () { Menus = []; }
  1107. public string MenuBar
  1108. {
  1109. get => _menuBar;
  1110. set
  1111. {
  1112. if (value == _menuBar)
  1113. {
  1114. return;
  1115. }
  1116. _menuBar = value;
  1117. PropertyChanged?.Invoke (
  1118. this,
  1119. new (GetPropertyName ())
  1120. );
  1121. }
  1122. }
  1123. public ObservableCollection<DynamicMenuItemList> Menus
  1124. {
  1125. get => _menus;
  1126. set
  1127. {
  1128. if (value == _menus)
  1129. {
  1130. return;
  1131. }
  1132. _menus = value;
  1133. PropertyChanged?.Invoke (
  1134. this,
  1135. new (GetPropertyName ())
  1136. );
  1137. }
  1138. }
  1139. public string Parent
  1140. {
  1141. get => _parent;
  1142. set
  1143. {
  1144. if (value == _parent)
  1145. {
  1146. return;
  1147. }
  1148. _parent = value;
  1149. PropertyChanged?.Invoke (
  1150. this,
  1151. new (GetPropertyName ())
  1152. );
  1153. }
  1154. }
  1155. public event PropertyChangedEventHandler PropertyChanged;
  1156. public string GetPropertyName ([CallerMemberName] string propertyName = null) { return propertyName; }
  1157. }
  1158. public interface IValueConverter
  1159. {
  1160. object Convert (object value, object parameter = null);
  1161. }
  1162. public class ListWrapperConverter<T> : IValueConverter
  1163. {
  1164. public object Convert (object value, object parameter = null) { return new ListWrapper<T> ((ObservableCollection<T>)value); }
  1165. }
  1166. public class UStringValueConverter : IValueConverter
  1167. {
  1168. public object Convert (object value, object parameter = null)
  1169. {
  1170. byte [] data = Encoding.ASCII.GetBytes (value.ToString () ?? string.Empty);
  1171. return StringExtensions.ToString (data);
  1172. }
  1173. }
  1174. }