private MenuItem CreateMenuItem(object sender, RepositoryAction action, IEnumerable <RepositoryView> affectedViews = null) { Action <object, object> clickAction = (object clickSender, object clickArgs) => { if (action?.Action != null) { var coords = new float[] { 0, 0 }; // run actions in the UI async to not block it if (action.ExecutionCausesSynchronizing) { Task.Run(() => SetViewsSynchronizing(affectedViews, true)) .ContinueWith(t => action.Action(null, coords)) .ContinueWith(t => SetViewsSynchronizing(affectedViews, false)); } else { Task.Run(() => action.Action(null, coords)); } } }; var item = new AcrylicMenuItem() { Header = action.Name, IsEnabled = action.CanExecute }; item.Click += new RoutedEventHandler(clickAction); // this is a deferred submenu. We want to make sure that the context menu can pop up // fast, while submenus are not evaluated yet. We don't want to make the context menu // itself slow because the creation of the submenu items takes some time. if (action.DeferredSubActionsEnumerator != null) { // this is a template submenu item to enable submenus under the current // menu item. this item gets removed when the real subitems are created item.Items.Add(""); void SelfDetachingEventHandler(object _, RoutedEventArgs __) { item.SubmenuOpened -= SelfDetachingEventHandler; item.Items.Clear(); foreach (var subAction in action.DeferredSubActionsEnumerator()) { item.Items.Add(CreateMenuItem(sender, subAction)); } Console.WriteLine($"Added {item.Items.Count} deferred sub action(s)."); } item.SubmenuOpened += SelfDetachingEventHandler; } return(item); }
private MenuItem CreateMenuItem(object sender, RepositoryAction action, IEnumerable <RepositoryView> affectedViews = null) { Action <object, object> clickAction = (object clickSender, object clickArgs) => { if (action?.Action != null) { var coords = new float[] { 0, 0 }; // run actions in the UI async to not block it if (action.ExecutionCausesSynchronizing) { Task.Run(() => SetViewsSynchronizing(affectedViews, true)) .ContinueWith(t => action.Action(null, coords)) .ContinueWith(t => SetViewsSynchronizing(affectedViews, false)); } else { Task.Run(() => action.Action(null, coords)); } } }; var item = new AcrylicMenuItem() { Header = action.Name, IsEnabled = action.CanExecute }; item.Click += new RoutedEventHandler(clickAction); if (action.SubActions != null) { foreach (var subAction in action.SubActions) { item.Items.Add(CreateMenuItem(sender, subAction)); } } return(item); }