DynamicMenuBar.cs 59 KB

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