DynamicMenuBar.cs 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413
  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 ("Arrangement")]
  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.Accepting += (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.SetNeedsDraw ();
  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.SetNeedsDraw ();
  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.CheckedStateChanged += (s, e) =>
  209. {
  210. if (e.CurrentValue == CheckState.Checked)
  211. {
  212. CkbIsTopLevel.CheckedState = CheckState.UnChecked;
  213. CkbIsTopLevel.SetNeedsDraw ();
  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.SetNeedsDraw ();
  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.CurrentValue == CheckState.UnChecked;
  235. }
  236. }
  237. };
  238. CkbNullCheck.CheckedStateChanged += (s, e) =>
  239. {
  240. if (_menuItem != null)
  241. {
  242. _menuItem.AllowNullChecked = e.CurrentValue == 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.Accepting += (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.Accepting += (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, 23, Application.Screen.Height) };
  355. Width = Dim.Fill ();
  356. Height = Dim.Fill () - 2;
  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 = Glyphs.UpArrow.ToString () };
  481. frmMenu.Add (btnMenuBarUp);
  482. var btnMenuBarDown = new Button { X = Pos.Center (), Y = Pos.Bottom (btnMenuBarUp), Text = 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 = 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 = 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 = Glyphs.UpArrow.ToString () };
  546. frmMenu.Add (btnUp);
  547. var btnDown = new Button { X = Pos.Right (_lstMenus) + 2, Y = Pos.Top (btnUp) + 1, Text = 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.Accepting += (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.SetNeedsDraw ();
  574. }
  575. }
  576. };
  577. btnMenuBarDown.Accepting += (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.SetNeedsDraw ();
  592. }
  593. }
  594. };
  595. btnUp.Accepting += (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.Accepting += (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.Accepting += (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.Accepting += (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.Accepting += (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.Accepting += (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 (MenuBar, newMenu);
  740. DataContext.Menus.Add (new () { Title = newMenu.Title, MenuItem = newMenu });
  741. _lstMenus.MoveDown ();
  742. }
  743. };
  744. btnRemove.Accepting += (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. if (_menuBar.Menus.Length == 0)
  770. {
  771. RemoveMenuBar ();
  772. }
  773. _lstMenus.SetNeedsDraw ();
  774. SetFrameDetails ();
  775. }
  776. };
  777. _lstMenus.OpenSelectedItem += (s, e) =>
  778. {
  779. _currentMenuBarItem = DataContext.Menus [e.Item].MenuItem;
  780. if (!(_currentMenuBarItem is MenuBarItem))
  781. {
  782. MessageBox.ErrorQuery ("Menu Open Error", "Must allows sub menus first!", "Ok");
  783. return;
  784. }
  785. DataContext.Parent = _currentMenuBarItem.Title;
  786. DataContext.Menus = new ();
  787. SetListViewSource (_currentMenuBarItem, true);
  788. MenuItem menuBarItem = DataContext.Menus.Count > 0 ? DataContext.Menus [0].MenuItem : null;
  789. SetFrameDetails (menuBarItem);
  790. };
  791. _lstMenus.HasFocusChanging += (s, e) =>
  792. {
  793. MenuItem menuBarItem = _lstMenus.SelectedItem > -1 && DataContext.Menus.Count > 0
  794. ? DataContext.Menus [_lstMenus.SelectedItem].MenuItem
  795. : null;
  796. SetFrameDetails (menuBarItem);
  797. };
  798. btnNext.Accepting += (s, e) =>
  799. {
  800. if (_menuBar != null && _currentSelectedMenuBar + 1 < _menuBar.Menus.Length)
  801. {
  802. _currentSelectedMenuBar++;
  803. }
  804. SelectCurrentMenuBarItem ();
  805. };
  806. btnPrevious.Accepting += (s, e) =>
  807. {
  808. if (_currentSelectedMenuBar - 1 > -1)
  809. {
  810. _currentSelectedMenuBar--;
  811. }
  812. SelectCurrentMenuBarItem ();
  813. };
  814. lblMenuBar.HasFocusChanging += (s, e) =>
  815. {
  816. if (_menuBar?.Menus != null)
  817. {
  818. _currentMenuBarItem = _menuBar.Menus [_currentSelectedMenuBar];
  819. SetFrameDetails (_menuBar.Menus [_currentSelectedMenuBar]);
  820. }
  821. };
  822. btnAddMenuBar.Accepting += (s, e) =>
  823. {
  824. var frameDetails = new DynamicMenuBarDetails (null);
  825. DynamicMenuItem item = frameDetails.EnterMenuItem ();
  826. if (item == null)
  827. {
  828. return;
  829. }
  830. if (MenuBar == null)
  831. {
  832. _menuBar = new ();
  833. Add (_menuBar);
  834. }
  835. var newMenu = CreateNewMenu (item) as MenuBarItem;
  836. newMenu.AddMenuBarItem (MenuBar);
  837. _currentMenuBarItem = newMenu;
  838. _currentMenuBarItem.CheckType = item.CheckStyle;
  839. if (Key.TryParse (item.ShortcutKey, out Key key))
  840. {
  841. _currentMenuBarItem.ShortcutKey = key;
  842. }
  843. _currentSelectedMenuBar = _menuBar.Menus.Length - 1;
  844. _menuBar.Menus [_currentSelectedMenuBar] = newMenu;
  845. lblMenuBar.Text = newMenu.Title;
  846. SetListViewSource (_currentMenuBarItem, true);
  847. SetFrameDetails (_menuBar.Menus [_currentSelectedMenuBar]);
  848. _menuBar.SetNeedsDraw ();
  849. };
  850. btnRemoveMenuBar.Accepting += (s, e) =>
  851. {
  852. if (_menuBar == null)
  853. {
  854. return;
  855. }
  856. if (_menuBar != null && _menuBar.Menus.Length > 0)
  857. {
  858. _currentMenuBarItem.RemoveMenuItem ();
  859. if (_currentSelectedMenuBar - 1 >= 0 && _menuBar.Menus.Length > 0)
  860. {
  861. _currentSelectedMenuBar--;
  862. }
  863. _currentMenuBarItem = _menuBar.Menus?.Length > 0
  864. ? _menuBar.Menus [_currentSelectedMenuBar]
  865. : null;
  866. }
  867. RemoveMenuBar ();
  868. SetListViewSource (_currentMenuBarItem, true);
  869. SetFrameDetails ();
  870. };
  871. void RemoveMenuBar ()
  872. {
  873. if (MenuBar != null && _currentMenuBarItem == null && _menuBar.Menus.Length == 0)
  874. {
  875. Remove (_menuBar);
  876. _menuBar.Dispose ();
  877. _menuBar = null;
  878. DataContext.Menus = new ();
  879. _currentMenuBarItem = null;
  880. _currentSelectedMenuBar = -1;
  881. lblMenuBar.Text = string.Empty;
  882. }
  883. else
  884. {
  885. lblMenuBar.Text = _menuBar.Menus [_currentSelectedMenuBar].Title;
  886. }
  887. }
  888. SetFrameDetails ();
  889. var ustringConverter = new UStringValueConverter ();
  890. ListWrapperConverter<DynamicMenuItemList> listWrapperConverter = new ListWrapperConverter<DynamicMenuItemList> ();
  891. var bdgMenuBar = new Binding (this, "MenuBar", lblMenuBar, "Text", ustringConverter);
  892. var bdgParent = new Binding (this, "Parent", lblParent, "Text", ustringConverter);
  893. var bdgMenus = new Binding (this, "Menus", _lstMenus, "Source", listWrapperConverter);
  894. void SetFrameDetails (MenuItem menuBarItem = null)
  895. {
  896. MenuItem menuItem;
  897. if (menuBarItem == null)
  898. {
  899. menuItem = _lstMenus.SelectedItem > -1 && DataContext.Menus.Count > 0
  900. ? DataContext.Menus [_lstMenus.SelectedItem].MenuItem
  901. : _currentEditMenuBarItem;
  902. }
  903. else
  904. {
  905. menuItem = menuBarItem;
  906. }
  907. _currentEditMenuBarItem = menuItem;
  908. frmMenuDetails.EditMenuBarItem (menuItem);
  909. bool f = btnOk.Enabled == frmMenuDetails.Enabled;
  910. if (!f)
  911. {
  912. btnOk.Enabled = frmMenuDetails.Enabled;
  913. btnCancel.Enabled = frmMenuDetails.Enabled;
  914. }
  915. }
  916. void SelectCurrentMenuBarItem ()
  917. {
  918. MenuBarItem menuBarItem = null;
  919. if (_menuBar?.Menus is { Length: > 0 })
  920. {
  921. menuBarItem = _menuBar.Menus [_currentSelectedMenuBar];
  922. lblMenuBar.Text = menuBarItem.Title;
  923. }
  924. SetFrameDetails (menuBarItem);
  925. _currentMenuBarItem = menuBarItem;
  926. DataContext.Menus = new ();
  927. SetListViewSource (_currentMenuBarItem, true);
  928. lblParent.Text = string.Empty;
  929. if (_currentMenuBarItem is null)
  930. {
  931. lblMenuBar.Text = string.Empty;
  932. }
  933. }
  934. void SetListViewSource (MenuItem currentMenuBarItem, bool fill = false)
  935. {
  936. DataContext.Menus = [];
  937. var menuBarItem = currentMenuBarItem as MenuBarItem;
  938. if (menuBarItem != null && menuBarItem?.Children == null)
  939. {
  940. return;
  941. }
  942. if (!fill)
  943. {
  944. return;
  945. }
  946. if (menuBarItem != null)
  947. {
  948. foreach (MenuItem child in menuBarItem?.Children)
  949. {
  950. var m = new DynamicMenuItemList { Title = child.Title, MenuItem = child };
  951. DataContext.Menus.Add (m);
  952. }
  953. }
  954. }
  955. MenuItem CreateNewMenu (DynamicMenuItem item, MenuItem parent = null)
  956. {
  957. MenuItem newMenu;
  958. if (item.HasSubMenu)
  959. {
  960. newMenu = new MenuBarItem (item.Title, new MenuItem [] { }, parent);
  961. }
  962. else if (parent != null)
  963. {
  964. newMenu = new (item.Title, item.Help, null, null, parent);
  965. newMenu.CheckType = item.CheckStyle;
  966. newMenu.Action = frmMenuDetails.CreateAction (newMenu, item);
  967. if (Key.TryParse (item.ShortcutKey, out Key key))
  968. {
  969. newMenu.ShortcutKey = key;
  970. }
  971. newMenu.AllowNullChecked = item.AllowNullChecked;
  972. }
  973. else if (item.IsTopLevel)
  974. {
  975. newMenu = new MenuBarItem (item.Title, item.Help, null);
  976. newMenu.Action = frmMenuDetails.CreateAction (newMenu, item);
  977. if (Key.TryParse (item.ShortcutKey, out Key key))
  978. {
  979. newMenu.ShortcutKey = key;
  980. }
  981. }
  982. else
  983. {
  984. newMenu = new MenuBarItem (item.Title, item.Help, null);
  985. ((MenuBarItem)newMenu).Children [0].Action =
  986. frmMenuDetails.CreateAction (newMenu, item);
  987. if (Key.TryParse (item.ShortcutKey, out Key key))
  988. {
  989. ((MenuBarItem)newMenu).Children [0].ShortcutKey = key;
  990. }
  991. }
  992. return newMenu;
  993. }
  994. void UpdateMenuItem (MenuItem currentEditMenuBarItem, DynamicMenuItem menuItem, int index)
  995. {
  996. currentEditMenuBarItem.Title = menuItem.Title;
  997. currentEditMenuBarItem.Help = menuItem.Help;
  998. currentEditMenuBarItem.CheckType = menuItem.CheckStyle;
  999. if (currentEditMenuBarItem.Parent is MenuBarItem parent
  1000. && parent.Children.Length == 1
  1001. && currentEditMenuBarItem.CheckType == MenuItemCheckStyle.Radio)
  1002. {
  1003. currentEditMenuBarItem.Checked = true;
  1004. }
  1005. if (menuItem.IsTopLevel && currentEditMenuBarItem is MenuBarItem)
  1006. {
  1007. ((MenuBarItem)currentEditMenuBarItem).Children = null;
  1008. currentEditMenuBarItem.Action =
  1009. frmMenuDetails.CreateAction (currentEditMenuBarItem, menuItem);
  1010. if (Key.TryParse (menuItem.ShortcutKey, out Key key))
  1011. {
  1012. currentEditMenuBarItem.ShortcutKey = key;
  1013. }
  1014. SetListViewSource (currentEditMenuBarItem, true);
  1015. }
  1016. else if (menuItem.HasSubMenu)
  1017. {
  1018. currentEditMenuBarItem.Action = null;
  1019. if (currentEditMenuBarItem is MenuBarItem && ((MenuBarItem)currentEditMenuBarItem).Children == null)
  1020. {
  1021. ((MenuBarItem)currentEditMenuBarItem).Children = new MenuItem [] { };
  1022. }
  1023. else if (currentEditMenuBarItem.Parent != null)
  1024. {
  1025. frmMenuDetails.UpdateParent (ref currentEditMenuBarItem);
  1026. }
  1027. else
  1028. {
  1029. currentEditMenuBarItem =
  1030. new MenuBarItem (
  1031. currentEditMenuBarItem.Title,
  1032. new MenuItem [] { },
  1033. currentEditMenuBarItem.Parent
  1034. );
  1035. }
  1036. SetListViewSource (currentEditMenuBarItem, true);
  1037. }
  1038. else if (currentEditMenuBarItem is MenuBarItem && currentEditMenuBarItem.Parent != null)
  1039. {
  1040. frmMenuDetails.UpdateParent (ref currentEditMenuBarItem);
  1041. currentEditMenuBarItem = new (
  1042. menuItem.Title,
  1043. menuItem.Help,
  1044. frmMenuDetails.CreateAction (currentEditMenuBarItem, menuItem),
  1045. null,
  1046. currentEditMenuBarItem.Parent
  1047. );
  1048. }
  1049. else
  1050. {
  1051. if (currentEditMenuBarItem is MenuBarItem)
  1052. {
  1053. ((MenuBarItem)currentEditMenuBarItem).Children = null;
  1054. DataContext.Menus = new ();
  1055. }
  1056. currentEditMenuBarItem.Action =
  1057. frmMenuDetails.CreateAction (currentEditMenuBarItem, menuItem);
  1058. if (Key.TryParse (menuItem.ShortcutKey, out Key key))
  1059. {
  1060. currentEditMenuBarItem.ShortcutKey = key;
  1061. }
  1062. }
  1063. if (currentEditMenuBarItem.Parent == null)
  1064. {
  1065. DataContext.MenuBar = currentEditMenuBarItem.Title;
  1066. }
  1067. else
  1068. {
  1069. if (DataContext.Menus.Count == 0)
  1070. {
  1071. DataContext.Menus.Add (
  1072. new ()
  1073. {
  1074. Title = currentEditMenuBarItem.Title, MenuItem = currentEditMenuBarItem
  1075. }
  1076. );
  1077. }
  1078. DataContext.Menus [index] =
  1079. new ()
  1080. {
  1081. Title = currentEditMenuBarItem.Title, MenuItem = currentEditMenuBarItem
  1082. };
  1083. }
  1084. currentEditMenuBarItem.CheckType = menuItem.CheckStyle;
  1085. SetFrameDetails (currentEditMenuBarItem);
  1086. }
  1087. //_frmMenuDetails.Initialized += (s, e) => _frmMenuDetails.Enabled = false;
  1088. }
  1089. public DynamicMenuItemModel DataContext { get; set; }
  1090. }
  1091. public class DynamicMenuItem
  1092. {
  1093. public string Action { get; set; } = string.Empty;
  1094. public bool AllowNullChecked { get; set; }
  1095. public MenuItemCheckStyle CheckStyle { get; set; }
  1096. public bool HasSubMenu { get; set; }
  1097. public string Help { get; set; } = string.Empty;
  1098. public bool IsTopLevel { get; set; }
  1099. public string HotKey { get; set; }
  1100. public string ShortcutKey { get; set; }
  1101. public string Title { get; set; } = "_New";
  1102. }
  1103. public class DynamicMenuItemList
  1104. {
  1105. public MenuItem MenuItem { get; set; }
  1106. public string Title { get; set; }
  1107. public override string ToString () { return $"{Title}, {MenuItem.HotKey}, {MenuItem.ShortcutKey} "; }
  1108. }
  1109. public class DynamicMenuItemModel : INotifyPropertyChanged
  1110. {
  1111. private string _menuBar;
  1112. private ObservableCollection<DynamicMenuItemList> _menus;
  1113. private string _parent;
  1114. public DynamicMenuItemModel () { Menus = []; }
  1115. public string MenuBar
  1116. {
  1117. get => _menuBar;
  1118. set
  1119. {
  1120. if (value == _menuBar)
  1121. {
  1122. return;
  1123. }
  1124. _menuBar = value;
  1125. PropertyChanged?.Invoke (
  1126. this,
  1127. new (GetPropertyName ())
  1128. );
  1129. }
  1130. }
  1131. public ObservableCollection<DynamicMenuItemList> Menus
  1132. {
  1133. get => _menus;
  1134. set
  1135. {
  1136. if (value == _menus)
  1137. {
  1138. return;
  1139. }
  1140. _menus = value;
  1141. PropertyChanged?.Invoke (
  1142. this,
  1143. new (GetPropertyName ())
  1144. );
  1145. }
  1146. }
  1147. public string Parent
  1148. {
  1149. get => _parent;
  1150. set
  1151. {
  1152. if (value == _parent)
  1153. {
  1154. return;
  1155. }
  1156. _parent = value;
  1157. PropertyChanged?.Invoke (
  1158. this,
  1159. new (GetPropertyName ())
  1160. );
  1161. }
  1162. }
  1163. public event PropertyChangedEventHandler PropertyChanged;
  1164. public string GetPropertyName ([CallerMemberName] string propertyName = null) { return propertyName; }
  1165. }
  1166. public interface IValueConverter
  1167. {
  1168. object Convert (object value, object parameter = null);
  1169. }
  1170. public class ListWrapperConverter<T> : IValueConverter
  1171. {
  1172. public object Convert (object value, object parameter = null) { return new ListWrapper<T> ((ObservableCollection<T>)value); }
  1173. }
  1174. public class UStringValueConverter : IValueConverter
  1175. {
  1176. public object Convert (object value, object parameter = null)
  1177. {
  1178. byte [] data = Encoding.ASCII.GetBytes (value.ToString () ?? string.Empty);
  1179. return StringExtensions.ToString (data);
  1180. }
  1181. }
  1182. }