diff --git a/AddIns/ICSharpCode.SharpDevelop.addin b/AddIns/ICSharpCode.SharpDevelop.addin index 16e0ae5a3a..32d40592a6 100644 --- a/AddIns/ICSharpCode.SharpDevelop.addin +++ b/AddIns/ICSharpCode.SharpDevelop.addin @@ -817,34 +817,28 @@ + command = "Cut"/> + command = "Copy"/> + command = "Paste"/> + command = "Delete"/> + command = "Undo"/> + command = "Redo"/> @@ -1256,43 +1250,37 @@ icon = "Icons.16x16.UndoIcon" type = "Item" shortcut = "Control|Z" - loadclasslazy = "false" - class = "ICSharpCode.SharpDevelop.Commands.Undo"/> + command = "Undo"/> + command = "Redo"/> + command = "Cut"/> + command = "Copy"/> + command = "Paste"/> + command = "Delete"/> @@ -1318,8 +1306,7 @@ label = "${res:XML.MainMenu.EditMenu.SelectAll}" type = "Item" shortcut = "Control|A" - loadclasslazy = "false" - class = "ICSharpCode.SharpDevelop.Commands.SelectAll"/> + command = "SelectAll"/> @@ -2204,7 +2191,7 @@ label = "${res:XML.MainMenu.EditMenu.Copy}" type = "Item" icon = "Icons.16x16.CopyIcon" - class = "ICSharpCode.SharpDevelop.Commands.Copy"/> + command = "Copy"/> diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj index d58c00d46e..ff896644dd 100644 --- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj +++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj @@ -725,6 +725,7 @@ + diff --git a/src/Main/Base/Project/Src/Commands/EditCommands.cs b/src/Main/Base/Project/Src/Commands/EditCommands.cs index fe08d8ab9f..e389520c5d 100644 --- a/src/Main/Base/Project/Src/Commands/EditCommands.cs +++ b/src/Main/Base/Project/Src/Commands/EditCommands.cs @@ -14,203 +14,6 @@ using ICSharpCode.SharpDevelop.Gui; namespace ICSharpCode.SharpDevelop.Commands { - public class Undo : AbstractMenuCommand - { - public override bool IsEnabled { - get { - IUndoHandler editable = (WorkbenchSingleton.Workbench.ActiveContent as IUndoHandler) ?? (WorkbenchSingleton.ActiveControl as IUndoHandler); - if (editable != null) { - return editable.EnableUndo; - } else { - TextBoxBase textBox = WorkbenchSingleton.ActiveControl as TextBoxBase; - if (textBox != null) { - return textBox.CanUndo; - } - } - return false; - } - } - - public override void Run() - { - IUndoHandler editable = (WorkbenchSingleton.Workbench.ActiveContent as IUndoHandler) ?? (WorkbenchSingleton.ActiveControl as IUndoHandler); - if (editable != null) { - editable.Undo(); - } else { - TextBoxBase textBox = WorkbenchSingleton.ActiveControl as TextBoxBase; - if (textBox != null) { - textBox.Undo(); - } - } - } - } - - public class Redo : AbstractMenuCommand - { - public override bool IsEnabled { - get { - IUndoHandler editable = (WorkbenchSingleton.Workbench.ActiveContent as IUndoHandler) ?? (WorkbenchSingleton.ActiveControl as IUndoHandler); - if (editable != null) { - return editable.EnableRedo; - } - return false; - } - } - - public override void Run() - { - IUndoHandler editable = (WorkbenchSingleton.Workbench.ActiveContent as IUndoHandler) ?? (WorkbenchSingleton.ActiveControl as IUndoHandler); - if (editable != null) { - editable.Redo(); - } - } - } - - public abstract class AbstractClipboardCommand : AbstractMenuCommand - { - protected abstract bool GetEnabled(IClipboardHandler editable); - protected abstract void Run(IClipboardHandler editable); - - public static IClipboardHandler GetClipboardHandlerWrapper(Control ctl) - { - TextBoxBase tb = ctl as TextBoxBase; - if (tb != null) - return new TextBoxWrapper(tb); - ComboBox cb = ctl as ComboBox; - if (cb != null && cb.DropDownStyle != ComboBoxStyle.DropDownList) - return new ComboBoxWrapper(cb); - return ctl as IClipboardHandler; - } - - private class TextBoxWrapper : IClipboardHandler - { - TextBoxBase textBox; - public TextBoxWrapper(TextBoxBase textBox) { - this.textBox = textBox; - } - public bool EnableCut { - get { return !textBox.ReadOnly && textBox.SelectionLength > 0; } - } - public bool EnableCopy { - get { return textBox.SelectionLength > 0; } - } - public bool EnablePaste { - get { return !textBox.ReadOnly; } - } - public bool EnableDelete { - get { return !textBox.ReadOnly && textBox.SelectionLength > 0; } - } - public bool EnableSelectAll { - get { return textBox.TextLength > 0; } - } - public void Cut() { textBox.Cut(); } - public void Copy() { textBox.Copy(); } - public void Paste() { textBox.Paste(); } - public void Delete() { textBox.SelectedText = ""; } - public void SelectAll() { textBox.SelectAll(); } - } - - private class ComboBoxWrapper : IClipboardHandler - { - ComboBox comboBox; - public ComboBoxWrapper(ComboBox comboBox) { - this.comboBox = comboBox; - } - public bool EnableCut { - get { return comboBox.SelectionLength > 0; } - } - public bool EnableCopy { - get { return comboBox.SelectionLength > 0; } - } - public bool EnablePaste { - get { return ClipboardHandling.GetClipboardContainsText(); } - } - public bool EnableDelete { - get { return true; } - } - public bool EnableSelectAll { - get { return comboBox.Text.Length > 0; } - } - public void Cut() { ClipboardWrapper.SetText(comboBox.SelectedText); comboBox.SelectedText = ""; } - public void Copy() { ClipboardWrapper.SetText(comboBox.SelectedText); } - public void Paste() { comboBox.SelectedText = ClipboardWrapper.GetText(); } - public void Delete() { comboBox.SelectedText = ""; } - public void SelectAll() { comboBox.SelectAll(); } - } - - public override bool IsEnabled { - get { - IClipboardHandler editable = WorkbenchSingleton.Workbench.ActiveContent as IClipboardHandler; - if (editable == null) - editable = GetClipboardHandlerWrapper(WorkbenchSingleton.ActiveControl); - if (editable != null) { - return GetEnabled(editable); - } - return false; - } - } - - public override void Run() - { - IClipboardHandler editable = WorkbenchSingleton.Workbench.ActiveContent as IClipboardHandler; - if (editable == null) - editable = GetClipboardHandlerWrapper(WorkbenchSingleton.ActiveControl); - if (editable != null) { - Run(editable); - } - } - } - - public class Cut : AbstractClipboardCommand - { - protected override bool GetEnabled(IClipboardHandler editable) { - return editable.EnableCut; - } - protected override void Run(IClipboardHandler editable) { - editable.Cut(); - } - } - - public class Copy : AbstractClipboardCommand - { - protected override bool GetEnabled(IClipboardHandler editable) { - return editable.EnableCopy; - } - protected override void Run(IClipboardHandler editable) { - editable.Copy(); - } - } - - public class Paste : AbstractClipboardCommand - { - protected override bool GetEnabled(IClipboardHandler editable) { - return editable.EnablePaste; - } - protected override void Run(IClipboardHandler editable) { - editable.Paste(); - } - } - - public class Delete : AbstractClipboardCommand - { - protected override bool GetEnabled(IClipboardHandler editable) { - return editable.EnableDelete; - } - protected override void Run(IClipboardHandler editable) { - editable.Delete(); - } - } - - public class SelectAll : AbstractClipboardCommand - { - protected override bool GetEnabled(IClipboardHandler editable) { - return editable.EnableSelectAll; - } - protected override void Run(IClipboardHandler editable) { - editable.SelectAll(); - } - } - public class WordCount : AbstractMenuCommand { public override void Run() diff --git a/src/Main/Base/Project/Src/Gui/AbstractViewContentHandlingLoadErrors.cs b/src/Main/Base/Project/Src/Gui/AbstractViewContentHandlingLoadErrors.cs index 1f27dfa1d3..5805ad16fd 100644 --- a/src/Main/Base/Project/Src/Gui/AbstractViewContentHandlingLoadErrors.cs +++ b/src/Main/Base/Project/Src/Gui/AbstractViewContentHandlingLoadErrors.cs @@ -50,7 +50,7 @@ namespace ICSharpCode.SharpDevelop.Gui if (userContent != value) { userContent = value; if (errorList.Count == 0) { - contentControl.SetContent(userContent); + contentControl.SetContent(userContent, this); } } } @@ -91,7 +91,7 @@ namespace ICSharpCode.SharpDevelop.Gui errorTextBox.Background = SystemColors.WindowBrush; } errorTextBox.Text = String.Concat(this.LoadErrorHeaderText, ex.ToString()); - contentControl.SetContent(errorTextBox); + contentControl.SetContent(errorTextBox, this); } Dictionary errorList = new Dictionary(); @@ -111,7 +111,7 @@ namespace ICSharpCode.SharpDevelop.Gui if (errorList.Count > 0) { errorList.Remove(file); if (errorList.Count == 0) { - contentControl.SetContent(userContent); + contentControl.SetContent(userContent, this); } else { ShowError(errorList.Values.First().exception); } diff --git a/src/Main/Base/Project/Src/Gui/Pads/ToolsPad.cs b/src/Main/Base/Project/Src/Gui/Pads/ToolsPad.cs index 0dd691ca6d..95efbaa1e2 100644 --- a/src/Main/Base/Project/Src/Gui/Pads/ToolsPad.cs +++ b/src/Main/Base/Project/Src/Gui/Pads/ToolsPad.cs @@ -45,7 +45,7 @@ namespace ICSharpCode.SharpDevelop.Gui { IToolsHost th = WorkbenchSingleton.Workbench.ActiveViewContent as IToolsHost; if (th != null && th.ToolsContent != null) { - contentControl.SetContent(th.ToolsContent); + contentControl.SetContent(th.ToolsContent, th); } else { contentControl.SetContent(StringParser.Parse("${res:SharpDevelop.SideBar.NoToolsAvailableForCurrentDocument}")); } diff --git a/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonPadContent.cs b/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonPadContent.cs index b03e0b77f9..e600e7f180 100644 --- a/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonPadContent.cs +++ b/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonPadContent.cs @@ -18,12 +18,12 @@ namespace ICSharpCode.SharpDevelop.Gui sealed class AvalonPadContent : DockableContent, IDisposable { PadDescriptor descriptor; - IPadContent content; + IPadContent padInstance; AvalonDockLayout layout; TextBlock placeholder; public IPadContent PadContent { - get { return content; } + get { return padInstance; } } public AvalonPadContent(AvalonDockLayout layout, PadDescriptor descriptor) @@ -49,9 +49,9 @@ namespace ICSharpCode.SharpDevelop.Gui { if (placeholder != null && placeholder.IsVisible && !layout.Busy) { placeholder.IsVisibleChanged -= AvalonPadContent_IsVisibleChanged; - content = descriptor.PadContent; - if (content != null) { - this.SetContent(content.Content); + padInstance = descriptor.PadContent; + if (padInstance != null) { + this.SetContent(padInstance.Content, padInstance); placeholder = null; } } @@ -59,8 +59,8 @@ namespace ICSharpCode.SharpDevelop.Gui public void Dispose() { - if (content != null) { - content.Dispose(); + if (padInstance != null) { + padInstance.Dispose(); } } } diff --git a/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonWorkbenchWindow.cs b/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonWorkbenchWindow.cs index 69a99be489..31efc4e22d 100644 --- a/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonWorkbenchWindow.cs +++ b/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonWorkbenchWindow.cs @@ -120,7 +120,7 @@ namespace ICSharpCode.SharpDevelop.Gui window.RegisterNewContent(item); if (Count == 1) { - window.SetContent(item.Content); + window.SetContent(item.Content, item); } else { if (Count == 2) { window.CreateViewTabControl(); @@ -129,13 +129,13 @@ namespace ICSharpCode.SharpDevelop.Gui TabItem oldPage = new TabItem(); oldPage.Header = StringParser.Parse(oldItem.TabPageText); - oldPage.SetContent(oldItem.Content); + oldPage.SetContent(oldItem.Content, oldItem); window.viewTabControl.Items.Add(oldPage); } TabItem newPage = new TabItem(); newPage.Header = StringParser.Parse(item.TabPageText); - newPage.SetContent(item.Content); + newPage.SetContent(item.Content, item); window.viewTabControl.Items.Insert(index, newPage); } @@ -151,7 +151,7 @@ namespace ICSharpCode.SharpDevelop.Gui if (Count < 2) { window.ClearContent(); if (Count == 1) { - window.SetContent(this[0].Content); + window.SetContent(this[0].Content, this[0]); } } else { window.viewTabControl.Items.RemoveAt(index); @@ -169,10 +169,10 @@ namespace ICSharpCode.SharpDevelop.Gui if (Count == 1) { window.ClearContent(); - window.SetContent(item.Content); + window.SetContent(item.Content, item); } else { TabItem page = (TabItem)window.viewTabControl.Items[index]; - page.SetContent(item.Content); + page.SetContent(item.Content, item); page.Header = StringParser.Parse(item.TabPageText); } window.UpdateActiveViewContent(); diff --git a/src/Main/Base/Project/Src/Gui/WorkbenchSingleton.cs b/src/Main/Base/Project/Src/Gui/WorkbenchSingleton.cs index 00474d5cea..21d0326dc1 100644 --- a/src/Main/Base/Project/Src/Gui/WorkbenchSingleton.cs +++ b/src/Main/Base/Project/Src/Gui/WorkbenchSingleton.cs @@ -57,22 +57,6 @@ namespace ICSharpCode.SharpDevelop.Gui } } - public static Control ActiveControl { - get { - return null; - /* - ContainerControl container = WorkbenchSingleton.MainForm; - Control ctl; - do { - ctl = container.ActiveControl; - if (ctl == null) - return container; - container = ctl as ContainerControl; - } while(container != null); - return ctl;*/ - } - } - /// /// This method handles the redraw all event for specific changed IDE properties /// diff --git a/src/Main/Base/Project/Src/Util/ExtensionMethods.cs b/src/Main/Base/Project/Src/Util/ExtensionMethods.cs index 7dce1ef302..8ac0588efa 100644 --- a/src/Main/Base/Project/Src/Util/ExtensionMethods.cs +++ b/src/Main/Base/Project/Src/Util/ExtensionMethods.cs @@ -126,52 +126,39 @@ namespace ICSharpCode.SharpDevelop /// inside the host isn't) /// public static void SetContent(this ContentControl contentControl, object content) + { + SetContent(contentControl, content, null); + } + + public static void SetContent(this ContentControl contentControl, object content, object serviceObject) { if (contentControl == null) throw new ArgumentNullException("contentControl"); + // serviceObject = object implementing the old clipboard/undo interfaces + // to allow WinForms AddIns to handle WPF commands + var host = contentControl.Content as SDWindowsFormsHost; if (host != null) { - if (host.Child == content) + if (host.Child == content) { + host.ServiceObject = serviceObject; return; + } host.Dispose(); } if (content is WinForms.Control) { - contentControl.Content = new SDWindowsFormsHost((WinForms.Control)content); + contentControl.Content = new SDWindowsFormsHost { + Child = (WinForms.Control)content, + ServiceObject = serviceObject, + DisposeChild = false + }; } else if (content is string) { - contentControl.Content = new TextBlock(new Run(content.ToString())) { TextWrapping = TextWrapping.Wrap }; + contentControl.Content = new TextBlock { + Text = content.ToString(), + TextWrapping = TextWrapping.Wrap + }; } else { contentControl.Content = content; } } - - /// - /// WindowsFormsHost that prevents its child from being disposed. - /// The default WindowsFormsHost disposes its child when the WPF application shuts down, - /// but some events in SharpDevelop occur after the WPF shutdown (e.g. SolutionClosed), so we must - /// not dispose pads that could still be handling them. - /// - class SDWindowsFormsHost : WinForms.Integration.WindowsFormsHost - { - public SDWindowsFormsHost(WinForms.Control child) - { - this.Child = child; - child.Disposed += child_Disposed; - } - - void child_Disposed(object sender, EventArgs e) - { - Dispose(); - } - - protected override void Dispose(bool disposing) - { - if (disposing && Child != null) { - Child.Disposed -= child_Disposed; - // prevent child from being disposed - Child = null; - } - base.Dispose(disposing); - } - } } } diff --git a/src/Main/Base/Project/Src/Util/SDWindowsFormsHost.cs b/src/Main/Base/Project/Src/Util/SDWindowsFormsHost.cs new file mode 100644 index 0000000000..b6dfd4c027 --- /dev/null +++ b/src/Main/Base/Project/Src/Util/SDWindowsFormsHost.cs @@ -0,0 +1,192 @@ +// +// +// +// +// $Revision$ +// + +using ICSharpCode.Core.WinForms; +using System; +using System.Windows.Forms; +using System.Windows.Forms.Integration; +using System.Windows.Input; +using ICSharpCode.SharpDevelop.DefaultEditor; +using ICSharpCode.SharpDevelop.Gui; + +namespace ICSharpCode.SharpDevelop +{ + /// + /// WindowsFormsHost used in SharpDevelop. + /// + public class SDWindowsFormsHost : WindowsFormsHost + { + public SDWindowsFormsHost() + { + this.DisposeChild = true; + CreateBindings(); + } + + #region Binding + void CreateBindings() + { + AddBinding(ApplicationCommands.Copy, (IClipboardHandler c) => c.Copy(), c => c.EnableCopy); + AddBinding(ApplicationCommands.Cut, (IClipboardHandler c) => c.Cut(), c => c.EnableCut); + AddBinding(ApplicationCommands.Paste, (IClipboardHandler c) => c.Paste(), c => c.EnablePaste); + AddBinding(ApplicationCommands.Delete, (IClipboardHandler c) => c.Delete(), c => c.EnableDelete); + AddBinding(ApplicationCommands.SelectAll, (IClipboardHandler c) => c.SelectAll(), c => c.EnableSelectAll); + AddBinding(ApplicationCommands.Help, (IContextHelpProvider h) => h.ShowHelp(), h => true); + AddBinding(ApplicationCommands.Undo, (IUndoHandler u) => u.Undo(), u => u.EnableUndo); + AddBinding(ApplicationCommands.Redo, (IUndoHandler u) => u.Redo(), u => u.EnableRedo); + } + + void AddBinding(ICommand command, Action execute, Predicate canExecute) where T : class + { + ExecutedRoutedEventHandler onExected = (sender, e) => { + var cbh = GetInterface(); + if (cbh != null) { + e.Handled = true; + if (canExecute(cbh)) + execute(cbh); + } + }; + CanExecuteRoutedEventHandler onCanExecute = (sender, e) => { + var cbh = GetInterface(); + if (cbh != null) { + e.Handled = true; + e.CanExecute = canExecute(cbh); + } + }; + this.CommandBindings.Add(new CommandBinding(command, onExected, onCanExecute)); + } + #endregion + + #region Service Object + /// + /// Gets/Sets the object that implements the IClipboardHandler, IUndoHandler etc. interfaces... + /// + public object ServiceObject { get; set; } + + T GetInterface() where T : class + { + T instance = this.ServiceObject as T; + if (instance == null) { + instance = GetServiceWrapper(GetActiveControl()) as T; + } + return instance; + } + + Control GetActiveControl() + { + ContainerControl container = null; + Control ctl = this.Child; + while (ctl != null) { + container = ctl as ContainerControl; + if (container == null) + return ctl; + ctl = container.ActiveControl; + } + return container; + } + + static object GetServiceWrapper(Control ctl) + { + TextBoxBase tb = ctl as TextBoxBase; + if (tb != null) + return new TextBoxWrapper(tb); + ComboBox cb = ctl as ComboBox; + if (cb != null && cb.DropDownStyle != ComboBoxStyle.DropDownList) + return new ComboBoxWrapper(cb); + return ctl; + } + + sealed class TextBoxWrapper : IClipboardHandler, IUndoHandler + { + TextBoxBase textBox; + public TextBoxWrapper(TextBoxBase textBox) { + this.textBox = textBox; + } + public bool EnableCut { + get { return !textBox.ReadOnly && textBox.SelectionLength > 0; } + } + public bool EnableCopy { + get { return textBox.SelectionLength > 0; } + } + public bool EnablePaste { + get { return !textBox.ReadOnly && ClipboardHandling.GetClipboardContainsText(); } + } + public bool EnableDelete { + get { return !textBox.ReadOnly && textBox.SelectionLength > 0; } + } + public bool EnableSelectAll { + get { return textBox.TextLength > 0; } + } + public void Cut() { textBox.Cut(); } + public void Copy() { textBox.Copy(); } + public void Paste() { textBox.Paste(); } + public void Delete() { textBox.SelectedText = ""; } + public void SelectAll() { textBox.SelectAll(); } + + public bool EnableUndo { get { return textBox.CanUndo; } } + public bool EnableRedo { get { return false; } } + + public void Undo() + { + textBox.Undo(); + } + + public void Redo() + { + } + } + + sealed class ComboBoxWrapper : IClipboardHandler + { + ComboBox comboBox; + public ComboBoxWrapper(ComboBox comboBox) { + this.comboBox = comboBox; + } + public bool EnableCut { + get { return comboBox.SelectionLength > 0; } + } + public bool EnableCopy { + get { return comboBox.SelectionLength > 0; } + } + public bool EnablePaste { + get { return ClipboardHandling.GetClipboardContainsText(); } + } + public bool EnableDelete { + get { return true; } + } + public bool EnableSelectAll { + get { return comboBox.Text.Length > 0; } + } + public void Cut() { ClipboardWrapper.SetText(comboBox.SelectedText); comboBox.SelectedText = ""; } + public void Copy() { ClipboardWrapper.SetText(comboBox.SelectedText); } + public void Paste() { comboBox.SelectedText = ClipboardWrapper.GetText(); } + public void Delete() { comboBox.SelectedText = ""; } + public void SelectAll() { comboBox.SelectAll(); } + } + #endregion + + /// + /// Gets/Sets whether the windows forms control will be disposed + /// when the WindowsFormsHost is disposed. + /// The default value is true. + /// + /// + /// The default WindowsFormsHost disposes its child when the WPF application shuts down, + /// but some events in SharpDevelop occur after the WPF shutdown (e.g. SolutionClosed), so we must + /// not dispose pads that could still be handling them. + /// + public bool DisposeChild { get; set; } + + protected override void Dispose(bool disposing) + { + if (disposing && !this.DisposeChild && Child != null) { + // prevent child from being disposed + Child = null; + } + base.Dispose(disposing); + } + } +} diff --git a/src/Main/Core/Project/Src/Services/MessageService/MessageService.cs b/src/Main/Core/Project/Src/Services/MessageService/MessageService.cs index 083b166266..628bb961ae 100644 --- a/src/Main/Core/Project/Src/Services/MessageService/MessageService.cs +++ b/src/Main/Core/Project/Src/Services/MessageService/MessageService.cs @@ -125,7 +125,7 @@ namespace ICSharpCode.Core /// public static bool AskQuestion(string question) { - return AskQuestion(StringParser.Parse(question), StringParser.Parse("${res:Global.QuestionText}")); + return AskQuestion(question, StringParser.Parse("${res:Global.QuestionText}")); } /// @@ -211,7 +211,9 @@ namespace ICSharpCode.Core { try { return String.Format(StringParser.Parse(formatstring), formatitems); - } catch (FormatException) { + } catch (FormatException ex) { + LoggingService.Warn(ex); + StringBuilder b = new StringBuilder(StringParser.Parse(formatstring)); foreach(string formatitem in formatitems) { b.Append("\nItem: "); diff --git a/src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs b/src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs index c5b3a132be..f8e91a598a 100644 --- a/src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs +++ b/src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs @@ -8,6 +8,7 @@ using System; using System.Collections; using System.Diagnostics; +using System.Reflection; using System.Threading; using System.Windows; using System.Windows.Controls; @@ -17,6 +18,25 @@ namespace ICSharpCode.Core.Presentation { class CommandWrapper : System.Windows.Input.ICommand { + public static System.Windows.Input.ICommand GetCommand(Codon codon, object caller, bool createCommand) + { + string commandName = codon.Properties["command"]; + if (!string.IsNullOrEmpty(commandName)) { + PropertyInfo p = typeof(ApplicationCommands).GetProperty(commandName); + if (p == null) { + p = typeof(NavigationCommands).GetProperty(commandName); + } + if (p != null) { + return (System.Windows.Input.ICommand)p.GetValue(null, null); + } else { + MessageService.ShowError("Could not find WPF command '" + commandName + "'."); + // return dummy command + return new CommandWrapper(codon, caller, null); + } + } + return new CommandWrapper(codon, caller, createCommand); + } + bool commandCreated; ICommand addInCommand; readonly Codon codon; @@ -101,7 +121,7 @@ namespace ICSharpCode.Core.Presentation { public MenuCommand(UIElement inputBindingOwner, Codon codon, object caller, bool createCommand) : base(codon, caller) { - this.Command = new CommandWrapper(codon, caller, createCommand); + this.Command = CommandWrapper.GetCommand(codon, caller, createCommand); if (!string.IsNullOrEmpty(codon.Properties["shortcut"])) { KeyGesture kg = MenuService.ParseShortcut(codon.Properties["shortcut"]); inputBindingOwner.InputBindings.Add( diff --git a/src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarButton.cs b/src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarButton.cs index a00e4317e4..1d4551995c 100644 --- a/src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarButton.cs +++ b/src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarButton.cs @@ -26,7 +26,7 @@ namespace ICSharpCode.Core.Presentation this.codon = codon; this.caller = caller; - this.Command = new CommandWrapper(codon, caller, createCommand); + this.Command = CommandWrapper.GetCommand(codon, caller, createCommand); if (codon.Properties.Contains("icon")) { var image = PresentationResourceService.GetImage(StringParser.Parse(codon.Properties["icon"]));