private static Tuple <ToolStripMenuItem, Action> InitializeActionMenuItem(BaseAssetForm <T> form, IEnumerable <Tuple <string[], Keys, int, MethodInfo> > data, out int priority) { var formType = form.GetType(); Delegate actionMethod = null; Delegate validationMethod = null; priority = -1; var shortcut = Keys.None; var actionDelegateType = typeof(Action <>).MakeGenericType(formType); var validationDelegateType = typeof(Func <,>).MakeGenericType(formType, typeof(bool)); foreach (var d in data) { if (actionMethod != null && validationMethod != null) { break; } if (actionMethod == null) { var d2 = Delegate.CreateDelegate(actionDelegateType, null, d.Item4, false); if (d2 != null) { actionMethod = d2; priority = d.Item3; shortcut = d.Item2; } } else { var d2 = Delegate.CreateDelegate(validationDelegateType, null, d.Item4, false); if (d2 != null) { validationMethod = d2; } } } if (actionMethod == null) { return(null); } var e = new ToolStripMenuItem { ShortcutKeys = shortcut }; e.Click += (sender, args) => { actionMethod.DynamicInvoke(form); }; Action validationAction = null; if (validationMethod != null) { validationAction = () => { e.Enabled = (bool)validationMethod.DynamicInvoke(form); }; } return(Tuple.Create(e, validationAction)); }
private static IEnumerable <System.Tuple <ToolStripMenuItem, int, IEnumerable <Action> > > BuildToolStripItems( BaseAssetForm <T> form, IEnumerable <Tuple <string[], Keys, int, MethodInfo> > data, int index) { var d2 = data.ToArray(); var group = d2.GroupBy(d => d.Item1[index]).OrderBy(g => g.Key); foreach (var g in group) { ToolStripMenuItem e; var priority = 0; var validationCallbacks = Enumerable.Empty <Action>(); var d3 = g.GroupBy(d => d.Item1.Length - index) .ToLookup(d => d.Key > 1, d => (IEnumerable <Tuple <string[], Keys, int, MethodInfo> >)g); var multi = d3[true].Any(); var single = d3[false].Any(); if (multi && single) { throw new Exception( $"Single menu item found on the same menu path as a multi tool. \"{d3[false].SelectMany(d => d).First().Item1.Aggregate((s1, s2) => s1 + "/" + s2)}\""); } if (single) { var t = InitializeActionMenuItem(form, g, out priority); if (t == null) { continue; } e = t.Item1; if (t.Item2 != null) { validationCallbacks = new[] { t.Item2 } } ; } else { var elements = BuildToolStripItems(form, g, index + 1).ToArray(); if (elements.Length == 0) { continue; } e = new ToolStripMenuItem(); e.DropDownItems.AddRange(elements.Sort(MenuItemSorter).Select(e2 => e2.Item1).Cast <ToolStripItem>().ToArray()); priority = 0; var callbacks = elements.SelectMany(e2 => e2.Item3).Where(a => a != null).ToArray(); if (callbacks.Length > 0) { e.DropDownOpening += (sender, args) => { foreach (var v in callbacks) { v(); } }; } } e.Text = g.Key; e.AutoSize = true; yield return(Tuple.Create(e, priority, validationCallbacks)); } }