diff --git a/AddIns/ICSharpCode.SharpDevelop.addin b/AddIns/ICSharpCode.SharpDevelop.addin
index 2704c381b5..6bf30ae0fe 100644
--- a/AddIns/ICSharpCode.SharpDevelop.addin
+++ b/AddIns/ICSharpCode.SharpDevelop.addin
@@ -52,7 +52,6 @@
-
+
@@ -136,7 +135,6 @@
-
diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs
index 2f1bd22834..83ce02ea27 100644
--- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs
+++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs
@@ -117,7 +117,13 @@ namespace ICSharpCode.AvalonEdit.AddIn
public CodeEditor()
{
- this.CommandBindings.Add(new CommandBinding(SharpDevelopRoutedCommands.SplitView, OnSplitView));
+ var contextName = this.GetType().FullName;
+ CommandsRegistry.RegisterCommandBindingsUpdateHandler(contextName, this, CommandsRegistry.CreateCommandBindingUpdateHandler(CommandBindings, contextName, this));
+ CommandsRegistry.RegisterInputBindingUpdateHandler(contextName, this, CommandsRegistry.CreateInputBindingUpdateHandler(InputBindings, contextName, this));
+ CommandsRegistry.RegisterCommandBinding(contextName, this, "SDWindowCommands.SplitView", OnSplitView, OnCanSplitView);
+
+ CommandsRegistry.InvokeCommandBindingUpdateHandlers(contextName, this);
+ CommandsRegistry.InvokeInputBindingUpdateHandlers(contextName, this);
textMarkerService = new TextMarkerService(this);
iconBarManager = new IconBarManager();
@@ -198,6 +204,10 @@ namespace ICSharpCode.AvalonEdit.AddIn
primaryTextEditor.Save(stream);
}
+ void OnCanSplitView(object sender, CanExecuteRoutedEventArgs e)
+ {
+ e.CanExecute = true;
+ }
void OnSplitView(object sender, ExecutedRoutedEventArgs e)
{
if (secondaryTextEditor == null) {
diff --git a/src/Main/Base/Project/Src/Commands/MenuItemBuilders.cs b/src/Main/Base/Project/Src/Commands/MenuItemBuilders.cs
index 9f6c0e6c2e..251b151887 100644
--- a/src/Main/Base/Project/Src/Commands/MenuItemBuilders.cs
+++ b/src/Main/Base/Project/Src/Commands/MenuItemBuilders.cs
@@ -456,6 +456,8 @@ namespace ICSharpCode.SharpDevelop.Commands
get;
}
+ public List bindingsAssigned = new List();
+
public ICollection BuildItems(Codon codon, object owner)
{
ArrayList list = new ArrayList();
@@ -467,33 +469,32 @@ namespace ICSharpCode.SharpDevelop.Commands
item.Icon = PresentationResourceService.GetPixelSnappedImage(padContent.Icon);
}
- // Dynamicaly create routed UI command for loaded pad
var routedCommandName = "SDViewCommands.ShowView_" + padContent.Class;
var routedCommandText = "Show view " + MenuService.ConvertLabel(StringParser.Parse(padContent.Title));
- CommandsRegistry.RegisterRoutedUICommand(routedCommandName, routedCommandText);
-
- // Register command which will activate loaded tab
- CommandsRegistry.LoadCommand(routedCommandName, new BringPadToFrontCommand(padContent));
-
- // Register command binding in workbench
- CommandsRegistry.RegisterCommandBinding(CommandsRegistry.DefaultContext, routedCommandName, routedCommandName, null, false);
- CommandsRegistry.InvokeCommandBindingUpdateHandlers(CommandsRegistry.DefaultContext);
-
- item.Command = CommandsRegistry.GetRoutedUICommand(routedCommandName);
- // If pad have shortcut specified add input binding
- if (!string.IsNullOrEmpty(padContent.Shortcut)) {
- var gestures = (InputGestureCollection)new InputGestureCollectionConverter().ConvertFromString(padContent.Shortcut);
- foreach(InputGesture gesture in gestures) {
- CommandsRegistry.RegisterInputBinding(CommandsRegistry.DefaultContext, routedCommandName, gesture);
+ // TODO: fix this hack
+ if(!bindingsAssigned.Contains(routedCommandName)) {
+ // Dynamicaly create routed UI command to loaded pad and bindings for it
+ CommandsRegistry.RegisterRoutedUICommand(routedCommandName, routedCommandText);
+ CommandsRegistry.LoadCommand(routedCommandName, new BringPadToFrontCommand(padContent));
+ CommandsRegistry.RegisterCommandBinding(CommandsRegistry.DefaultContext, null, routedCommandName, routedCommandName, null, false);
+
+ // If pad have shortcut specified add input binding
+ if (!string.IsNullOrEmpty(padContent.Shortcut)) {
+ var gestures = (InputGestureCollection)new InputGestureCollectionConverter().ConvertFromString(padContent.Shortcut);
+ foreach(InputGesture gesture in gestures) {
+ CommandsRegistry.RegisterInputBinding(CommandsRegistry.DefaultContext, null, routedCommandName, gesture);
+ }
}
- item.InputGestureText = "M: " + padContent.Shortcut;
- } else {
- item.InputGestureText = "M: ";
+ bindingsAssigned.Add(routedCommandName);
}
- CommandsRegistry.InvokeInputBindingUpdateHandlers(CommandsRegistry.DefaultContext);
+ CommandsRegistry.InvokeCommandBindingUpdateHandlers(CommandsRegistry.DefaultContext, null);
+ CommandsRegistry.InvokeInputBindingUpdateHandlers(CommandsRegistry.DefaultContext, null);
+
+ item.InputGestureText = padContent.Shortcut;
+ item.Command = CommandsRegistry.GetRoutedUICommand(routedCommandName);
// item.Command = new BringPadToFrontCommand(padContent);
// if (!string.IsNullOrEmpty(padContent.Shortcut)) {
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 56b671b5d6..710745bef2 100644
--- a/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonPadContent.cs
+++ b/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonPadContent.cs
@@ -91,19 +91,10 @@ namespace ICSharpCode.SharpDevelop.Gui
CommandsRegistry.LoadContext(contextName, (UIElement)Content);
- CommandsRegistry.RegisterCommandBindingsUpdateHandler(contextName, delegate {
- var bindings = CommandsRegistry.GetCommandBindings(contextName, null, null);
- CommandsRegistry.RemoveManagedCommandBindings(CommandBindings);
- CommandBindings.AddRange(bindings);
- });
-
- CommandsRegistry.RegisterInputBindingUpdateHandler(contextName, delegate {
- var bindings = CommandsRegistry.GetInputBindings(contextName, null, null);
- CommandsRegistry.RemoveManagedInputBindings(InputBindings);
- InputBindings.AddRange(bindings);
- });
- CommandsRegistry.InvokeCommandBindingUpdateHandlers(contextName);
- CommandsRegistry.InvokeInputBindingUpdateHandlers(contextName);
+ CommandsRegistry.RegisterCommandBindingsUpdateHandler(contextName, null, CommandsRegistry.CreateCommandBindingUpdateHandler(CommandBindings, contextName, null));
+ CommandsRegistry.RegisterInputBindingUpdateHandler(contextName, null, CommandsRegistry.CreateInputBindingUpdateHandler(InputBindings, contextName, null));
+ CommandsRegistry.InvokeCommandBindingUpdateHandlers(contextName, null);
+ CommandsRegistry.InvokeInputBindingUpdateHandlers(contextName, null);
}
}
}
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 c7ed197943..3dd774d97f 100644
--- a/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonWorkbenchWindow.cs
+++ b/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonWorkbenchWindow.cs
@@ -97,23 +97,11 @@ namespace ICSharpCode.SharpDevelop.Gui
CommandsRegistry.LoadContext(contextName, (UIElement)Content);
- CommandsRegistry.RegisterCommandBindingsUpdateHandler(
- contextName,
- delegate {
- var bindings = CommandsRegistry.GetCommandBindings(contextName, null, null);
- CommandsRegistry.RemoveManagedCommandBindings(CommandBindings);
- CommandBindings.AddRange(bindings);
- });
- CommandsRegistry.RegisterInputBindingUpdateHandler(
- contextName,
- delegate {
- var bindings = CommandsRegistry.GetInputBindings(contextName, null, null);
- CommandsRegistry.RemoveManagedInputBindings(InputBindings);
- InputBindings.AddRange(bindings);
- });
- CommandsRegistry.InvokeCommandBindingUpdateHandlers(contextName);
- CommandsRegistry.InvokeInputBindingUpdateHandlers(contextName);
+ CommandsRegistry.RegisterCommandBindingsUpdateHandler(contextName, null, CommandsRegistry.CreateCommandBindingUpdateHandler(CommandBindings, contextName, null));
+ CommandsRegistry.RegisterInputBindingUpdateHandler(contextName, null, CommandsRegistry.CreateInputBindingUpdateHandler(InputBindings, contextName, null));
+ CommandsRegistry.InvokeCommandBindingUpdateHandlers(contextName, null);
+ CommandsRegistry.InvokeInputBindingUpdateHandlers(contextName, null);
}
}
diff --git a/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs b/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs
index fca7208fdf..a8e5c9a48f 100644
--- a/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs
+++ b/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs
@@ -92,20 +92,10 @@ namespace ICSharpCode.SharpDevelop.Gui
// Register context and load all commands from addin
CommandsRegistry.LoadAddinCommands(AddInTree.AddIns.FirstOrDefault(a => a.Name == "SharpDevelop"));
- CommandsRegistry.RegisterCommandBindingsUpdateHandler(CommandsRegistry.DefaultContext, delegate {
- var bindings = CommandsRegistry.GetCommandBindings(CommandsRegistry.DefaultContext, null, null);
- CommandsRegistry.RemoveManagedCommandBindings(CommandBindings);
- CommandBindings.AddRange(bindings);
- });
-
- CommandsRegistry.RegisterInputBindingUpdateHandler(CommandsRegistry.DefaultContext, delegate {
- var bindings = CommandsRegistry.GetInputBindings(CommandsRegistry.DefaultContext, null, null);
- CommandsRegistry.RemoveManagedInputBindings(InputBindings);
- InputBindings.AddRange(bindings);
- });
-
- CommandsRegistry.InvokeCommandBindingUpdateHandlers(CommandsRegistry.DefaultContext);
- CommandsRegistry.InvokeInputBindingUpdateHandlers(CommandsRegistry.DefaultContext);
+ CommandsRegistry.RegisterCommandBindingsUpdateHandler(CommandsRegistry.DefaultContext, null, CommandsRegistry.CreateCommandBindingUpdateHandler(CommandBindings, CommandsRegistry.DefaultContext, null));
+ CommandsRegistry.RegisterInputBindingUpdateHandler(CommandsRegistry.DefaultContext, null, CommandsRegistry.CreateInputBindingUpdateHandler(InputBindings, CommandsRegistry.DefaultContext, null));
+ CommandsRegistry.InvokeCommandBindingUpdateHandlers(CommandsRegistry.DefaultContext, null);
+ CommandsRegistry.InvokeInputBindingUpdateHandlers(CommandsRegistry.DefaultContext, null);
mainMenu.ItemsSource = MenuService.CreateMenuItems(this, this, mainMenuPath);
diff --git a/src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandBindingInfo.cs b/src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandBindingInfo.cs
index 21a9b1fa56..bfca7ba074 100644
--- a/src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandBindingInfo.cs
+++ b/src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandBindingInfo.cs
@@ -9,6 +9,8 @@ namespace ICSharpCode.Core.Presentation
///
public class CommandBindingInfo
{
+ private UIElement contextInstance;
+
///
/// Constructor
///
@@ -24,6 +26,30 @@ namespace ICSharpCode.Core.Presentation
IsLazy = isLazy;
AddIn = addIn;
}
+
+ public CommandBindingInfo(string contextName, UIElement contextInstance, string routedCommandName, string className, AddIn addIn, bool isLazy) {
+ RoutedCommandName = routedCommandName;
+ ContextName = contextName;
+ ClassName = className;
+ IsLazy = isLazy;
+ AddIn = addIn;
+ this.contextInstance = contextInstance;
+ }
+
+ public CommandBindingInfo(string contextName, string routedCommandName, ExecutedRoutedEventHandler executedHandler, CanExecuteRoutedEventHandler canExecuteHandler) {
+ RoutedCommandName = routedCommandName;
+ ContextName = contextName;
+ this.executedEventHandler = executedHandler;
+ this.canExecutedEventHandler = canExecuteHandler;
+ }
+
+ public CommandBindingInfo(string contextName, UIElement contextInstance, string routedCommandName, ExecutedRoutedEventHandler executedHandler, CanExecuteRoutedEventHandler canExecuteHandler) {
+ RoutedCommandName = routedCommandName;
+ ContextName = contextName;
+ this.executedEventHandler = executedHandler;
+ this.canExecutedEventHandler = canExecuteHandler;
+ this.contextInstance = contextInstance;
+ }
///
/// Routed command name
@@ -101,10 +127,14 @@ namespace ICSharpCode.Core.Presentation
///
public UIElement Context {
get {
- UIElement context;
- CommandsRegistry.contexts.TryGetValue(ContextName, out context);
-
- return context;
+ if(contextInstance != null) {
+ return contextInstance;
+ } else {
+ UIElement context;
+ CommandsRegistry.contexts.TryGetValue(ContextName, out context);
+
+ return context;
+ }
}
}
@@ -118,5 +148,38 @@ namespace ICSharpCode.Core.Presentation
public bool IsLazy{
get; private set;
}
+
+ private ExecutedRoutedEventHandler executedEventHandler;
+ public void ExecutedEventHandler(object sender, ExecutedRoutedEventArgs e) {
+ if(executedEventHandler != null) {
+ executedEventHandler.Invoke(sender, e);
+ } else {
+ if(IsLazy && Class == null) {
+ AddIn.LoadRuntimeAssemblies();
+
+ var command = (ICommand)AddIn.CreateObject(ClassName);
+ CommandsRegistry.LoadCommand(ClassName, command);
+ }
+
+ if(Class != null) {
+ Class.Execute(e.Parameter);
+ }
+ }
+ }
+
+ private CanExecuteRoutedEventHandler canExecutedEventHandler;
+ public void CanExecuteEventHandler(object sender, CanExecuteRoutedEventArgs e) {
+ if(canExecutedEventHandler != null) {
+ canExecutedEventHandler.Invoke(sender, e);
+ } else {
+ if(IsLazy && Class == null) {
+ e.CanExecute = true;
+ } else if(Class == null) {
+ e.CanExecute = false;
+ } else {
+ e.CanExecute = Class.CanExecute(e.Parameter);
+ }
+ }
+ }
}
}
diff --git a/src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandsRegistry.cs b/src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandsRegistry.cs
index e4f285943e..cefd146e7e 100644
--- a/src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandsRegistry.cs
+++ b/src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandsRegistry.cs
@@ -14,6 +14,11 @@ namespace ICSharpCode.Core.Presentation
///
public static class CommandsRegistry
{
+ ///
+ /// This element is used to represent null key in dictionary
+ ///
+ private static UIElement NullUIElement = new UIElement();
+
///
/// Default application context.
///
@@ -30,8 +35,8 @@ namespace ICSharpCode.Core.Presentation
internal static Dictionary commands = new Dictionary();
internal static Dictionary contexts = new Dictionary();
- private static Dictionary> commandBindingsUpdateHandlers = new Dictionary>();
- private static Dictionary> inputBindingsUpdateHandlers = new Dictionary>();
+ private static Dictionary>> commandBindingsUpdateHandlers = new Dictionary>>();
+ private static Dictionary>> inputBindingsUpdateHandlers = new Dictionary>>();
///
/// Get reference to routed UI command by name
@@ -45,20 +50,48 @@ namespace ICSharpCode.Core.Presentation
return null;
}
+
+ ///
+ /// Checks whether routed UI command registered
+ ///
+ /// Routed command name
+ /// Returns value specifting whether routed UI command is registered
+ public static bool IsRoutedUICommandRegistered(string routedCommandName) {
+ return GetRoutedUICommand(routedCommandName) != null;
+ }
///
/// Register new routed command in the global registry
///
- /// Routed command name should be uniq in SharpDevelop scope.
- /// Use "." to emulate namespaces
+ /// Routed command name should be unique in SharpDevelop scope.
+ /// Use "." to organize commands into groups
///
/// Routed command name
/// Short text describing command functionality
public static void RegisterRoutedUICommand(string routedCommandName, string text) {
- var routedCommand = new RoutedUICommand(text, routedCommandName, typeof(UIElement));
+ var routedCommand = new RoutedUICommand(text, routedCommandName, typeof(CommandsRegistry));
if(!routedCommands.ContainsKey(routedCommandName)) {
routedCommands.Add(routedCommandName, routedCommand);
+ } else {
+ var test = routedCommands[routedCommandName];
+ throw new IndexOutOfRangeException("Routed UI command with name " + routedCommandName + " is already registered");
+ }
+ }
+
+ ///
+ /// Register existing routed command in the global registry
+ ///
+ /// Routed command then can be accessed
+ /// Routed command name should be uniq in SharpDevelop scope.
+ /// Use "." to organize commands into groups
+ ///
+ /// Existing routed command
+ public static void RegisterRoutedUICommand(RoutedUICommand existingRoutedUICommand) {
+ string routedCommandName = existingRoutedUICommand.OwnerType.Name + "." + existingRoutedUICommand.Name;
+
+ if(!routedCommands.ContainsKey(routedCommandName)) {
+ routedCommands.Add(existingRoutedUICommand.OwnerType.Name + "." + existingRoutedUICommand.Name, existingRoutedUICommand);
} else {
throw new IndexOutOfRangeException("Routed UI command with name " + routedCommandName + " is already registered");
}
@@ -75,16 +108,17 @@ namespace ICSharpCode.Core.Presentation
}
///
- /// Register several input bindings with the same
+ /// Register input binding in context
///
- /// Registering input binding means that when provided gesture is met in specified
- /// context routed command will be invoked
+ /// Registering input binding means that when specified gesture is met in specified
+ /// context routed command is invoked
///
/// Context class full name
+ /// Context class instance. If instance is provided this input binding only applies to provided UI element
/// Routed UI command invoked on gesture run
/// Gesture
- public static void RegisterInputBinding(string contextName, string routedCommandName, InputGesture gesture) {
- var inputBindingInfo = new InputBindingInfo(contextName, routedCommandName, gesture);
+ public static void RegisterInputBinding(string contextName, UIElement contextInstance, string routedCommandName, InputGesture gesture) {
+ var inputBindingInfo = new InputBindingInfo(contextName, contextInstance, routedCommandName, gesture);
inputBidnings.Add(inputBindingInfo);
}
@@ -94,11 +128,13 @@ namespace ICSharpCode.Core.Presentation
/// Null arguments are ignored
///
/// Context class full name
+ /// Unregister binding assigned to specific context instance
/// Routed UI command name
/// Gesture
- public static void UnregisterInputBindings(string contextName, string routedCommandName, InputGesture gesture) {
+ public static void UnregisterInputBindings(string contextName, UIElement contextInstance, string routedCommandName, InputGesture gesture) {
for(int i = inputBidnings.Count - 1; i >= 0; i--) {
if((contextName == null || inputBidnings[i].ContextName == contextName)
+ && (contextInstance == null || inputBidnings[i].Context == null || inputBidnings[i].Context == contextInstance)
&& (routedCommandName == null || inputBidnings[i].RoutedCommandName == routedCommandName)
&& (gesture == null || inputBidnings[i].Gesture == gesture)) {
inputBidnings.RemoveAt(i);
@@ -110,25 +146,40 @@ namespace ICSharpCode.Core.Presentation
/// Register delegate which will be invoked on change in input bindings in specified context
///
/// Context class full name
+ /// Register update handler which will trigger only if input bindings registered for this object where triggered
/// Update handler delegate
- public static void RegisterInputBindingUpdateHandler(string contextName, BindingsUpdatedHandler handler) {
+ public static void RegisterInputBindingUpdateHandler(string contextName, UIElement contextInstance, BindingsUpdatedHandler handler) {
+ if(contextInstance == null) {
+ contextInstance = NullUIElement;
+ }
+
if(!inputBindingsUpdateHandlers.ContainsKey(contextName)) {
- inputBindingsUpdateHandlers.Add(contextName, new List());
+ inputBindingsUpdateHandlers.Add(contextName, new Dictionary>());
}
- inputBindingsUpdateHandlers[contextName].Add(new WeakReference(handler));
+ if(!inputBindingsUpdateHandlers[contextName].ContainsKey(contextInstance)) {
+ inputBindingsUpdateHandlers[contextName].Add(contextInstance, new List());
+ }
+
+ inputBindingsUpdateHandlers[contextName][contextInstance].Add(handler);
}
///
/// Remove input bindings update handler
///
/// Context class full name
+ /// Unregister update handler which was triggered only if input bindings registered for specific instance where updated
/// Update handler delegate
- public static void UnregisterInputBindingUpdateHandler(string contextName, BindingsUpdatedHandler handler) {
+ public static void UnregisterInputBindingUpdateHandler(string contextName, UIElement contextInstance, BindingsUpdatedHandler handler) {
+ if(contextInstance == null) {
+ contextInstance = NullUIElement;
+ }
if(!inputBindingsUpdateHandlers.ContainsKey(contextName)) {
- for(int i = inputBindingsUpdateHandlers[contextName].Count - 1; i >= 0; i++) {
- if(inputBindingsUpdateHandlers[contextName][i].Target == handler) {
- inputBindingsUpdateHandlers[contextName].RemoveAt(i);
+ if(!inputBindingsUpdateHandlers[contextName].ContainsKey(contextInstance)) {
+ for(int i = inputBindingsUpdateHandlers[contextName][contextInstance].Count - 1; i >= 0; i++) {
+ if(inputBindingsUpdateHandlers[contextName][contextInstance][i] == handler) {
+ inputBindingsUpdateHandlers[contextName][contextInstance].RemoveAt(i);
+ }
}
}
}
@@ -139,20 +190,36 @@ namespace ICSharpCode.Core.Presentation
/// Invoke registered input bindings update handlers registered in specified context
///
/// Context class full name
- public static void InvokeInputBindingUpdateHandlers(string contextName) {
+ public static void InvokeInputBindingUpdateHandlers(string contextName, UIElement contextInstance) {
+ if(contextInstance == null) {
+ contextInstance = NullUIElement;
+ }
+
if(contextName != null) {
if(inputBindingsUpdateHandlers.ContainsKey(contextName)) {
- foreach(var handler in inputBindingsUpdateHandlers[contextName]) {
- if(handler != null && handler.Target != null) {
- ((BindingsUpdatedHandler)handler.Target).Invoke();
+ if(contextInstance == NullUIElement) {
+ foreach(var instanceHandlers in inputBindingsUpdateHandlers[contextName]) {
+ foreach(var handler in instanceHandlers.Value) {
+ if(handler != null) {
+ ((BindingsUpdatedHandler)handler).Invoke();
+ }
+ }
}
}
+ } else if(inputBindingsUpdateHandlers[contextName].ContainsKey(contextInstance)) {
+ foreach(var handler in inputBindingsUpdateHandlers[contextName][contextInstance]) {
+ if(handler != null) {
+ ((BindingsUpdatedHandler)handler).Invoke();
+ }
+ }
}
} else {
foreach(var contextHandlers in inputBindingsUpdateHandlers) {
- foreach(var handler in contextHandlers.Value) {
- if(handler != null && handler.Target != null) {
- ((BindingsUpdatedHandler)handler.Target).Invoke();
+ foreach(var instanceHandlers in contextHandlers.Value) {
+ foreach(var handler in instanceHandlers.Value) {
+ if(handler != null) {
+ ((BindingsUpdatedHandler)handler).Invoke();
+ }
}
}
}
@@ -178,12 +245,26 @@ namespace ICSharpCode.Core.Presentation
/// in specified context event is routed to specified command (implementing ICommand class)
///
/// Context class full name
+ /// Register update handler which is triggered only if input bindings registered for specific instance are updated
/// Routed UI command name
/// Command full name to which invokation event is routed
/// Add-in in which hosts the command
/// Load add-in referenced assemblies on command invocation
- public static void RegisterCommandBinding(string contextName, string routedCommandName, string className, AddIn addIn, bool isLazy) {
- var commandBindingInfo = new CommandBindingInfo(contextName, routedCommandName, className, addIn, isLazy);
+ public static void RegisterCommandBinding(string contextName, UIElement contextInstance, string routedCommandName, string className, AddIn addIn, bool isLazy) {
+ var commandBindingInfo = new CommandBindingInfo(contextName, contextInstance, routedCommandName, className, addIn, isLazy);
+ commandBindings.Add(commandBindingInfo);
+ }
+
+ ///
+ /// Register command binding which when triggered provided delegates are invoked
+ ///
+ /// Context class full name
+ /// Register update handler which is triggered only if input bindings registered for specific instance are updated
+ /// Routed UI command name
+ /// Delegate which is called when binding is triggered
+ /// Delegate which is called to check whether executedEventHandler can be invoked
+ public static void RegisterCommandBinding(string contextName, UIElement contextInstance, string routedCommandName, ExecutedRoutedEventHandler executedEventHandler, CanExecuteRoutedEventHandler canExecuteEventHandler) {
+ var commandBindingInfo = new CommandBindingInfo(contextName, contextInstance, routedCommandName, executedEventHandler, canExecuteEventHandler);
commandBindings.Add(commandBindingInfo);
}
@@ -193,11 +274,13 @@ namespace ICSharpCode.Core.Presentation
/// Null arguments are ignored
///
/// Context class full name
+ /// Unregister update handler which was triggered only if command bindings registered for specific instance where updated
/// Routed UI command name
/// Command full name to which invokation event is routed
- public static void UnregisterCommandBindings(string contextName, string routedCommandName, string className) {
+ public static void UnregisterCommandBindings(string contextName, UIElement contextInstance, string routedCommandName, string className) {
for(int i = commandBindings.Count - 1; i >= 0; i--) {
if((contextName == null || commandBindings[i].ContextName == contextName)
+ && (contextInstance == null || commandBindings[i].Context == null || commandBindings[i].Context == contextInstance)
&& (routedCommandName == null || commandBindings[i].RoutedCommandName == routedCommandName)
&& (className == null || commandBindings[i].ClassName == className)) {
inputBidnings.RemoveAt(i);
@@ -209,25 +292,39 @@ namespace ICSharpCode.Core.Presentation
/// Register delegate which will be invoked on any chage in command bindings of specified context
///
/// Context class full name
+ /// Register update handler which is triggered only if input bindings registered for specific instance are updated
/// Update handler delegate
- public static void RegisterCommandBindingsUpdateHandler(string contextName, BindingsUpdatedHandler handler) {
+ public static void RegisterCommandBindingsUpdateHandler(string contextName, UIElement contextInstance, BindingsUpdatedHandler handler) {
+ if(contextInstance == null) {
+ contextInstance = NullUIElement;
+ }
if(!commandBindingsUpdateHandlers.ContainsKey(contextName)) {
- commandBindingsUpdateHandlers.Add(contextName, new List());
+ commandBindingsUpdateHandlers.Add(contextName, new Dictionary>());
+ }
+
+ if(!commandBindingsUpdateHandlers[contextName].ContainsKey(contextInstance)) {
+ commandBindingsUpdateHandlers[contextName].Add(contextInstance, new List());
}
- commandBindingsUpdateHandlers[contextName].Add(new WeakReference(handler));
+ commandBindingsUpdateHandlers[contextName][contextInstance].Add(handler);
}
///
/// Remove handler command bindings update handler
///
/// Context class full name
+ /// Unregister update handler which was triggered only if input bindings registered for specific instance were updated
/// Update handler delegate
- public static void UnregisterCommandBindingsUpdateHandler(string contextName, BindingsUpdatedHandler handler) {
+ public static void UnregisterCommandBindingsUpdateHandler(string contextName, UIElement contextInstance, BindingsUpdatedHandler handler) {
+ if(contextInstance == null) {
+ contextInstance = NullUIElement;
+ }
if(commandBindingsUpdateHandlers.ContainsKey(contextName)) {
- for(int i = commandBindingsUpdateHandlers[contextName].Count - 1; i >= 0; i--) {
- if(commandBindingsUpdateHandlers[contextName][i].Target == handler) {
- commandBindingsUpdateHandlers[contextName].RemoveAt(i);
+ if(commandBindingsUpdateHandlers[contextName].ContainsKey(contextInstance)) {
+ for(int i = commandBindingsUpdateHandlers[contextName][contextInstance].Count - 1; i >= 0; i--) {
+ if(commandBindingsUpdateHandlers[contextName][contextInstance][i] == handler) {
+ commandBindingsUpdateHandlers[contextName][contextInstance].RemoveAt(i);
+ }
}
}
}
@@ -237,20 +334,37 @@ namespace ICSharpCode.Core.Presentation
/// Invoke registered command bindings update handlers registered in specified context
///
/// Context class full name
- public static void InvokeCommandBindingUpdateHandlers(string contextName) {
+ /// Invoke update handlers which handle update only in specifyc context
+ public static void InvokeCommandBindingUpdateHandlers(string contextName, UIElement contextInstance) {
+ if(contextInstance == null) {
+ contextInstance = NullUIElement;
+ }
+
if(contextName != null) {
if(commandBindingsUpdateHandlers.ContainsKey(contextName)) {
- foreach(var handler in commandBindingsUpdateHandlers[contextName]) {
- if(handler != null && handler.Target != null) {
- ((BindingsUpdatedHandler)handler.Target).Invoke();
+ if(contextInstance == NullUIElement) {
+ foreach(var instanceHandlers in commandBindingsUpdateHandlers[contextName]) {
+ foreach(var handler in instanceHandlers.Value) {
+ if(handler != null) {
+ ((BindingsUpdatedHandler)handler).Invoke();
+ }
+ }
+ }
+ } else if(commandBindingsUpdateHandlers[contextName].ContainsKey(contextInstance)) {
+ foreach(var handler in commandBindingsUpdateHandlers[contextName][contextInstance]) {
+ if(handler != null) {
+ ((BindingsUpdatedHandler)handler).Invoke();
+ }
}
}
}
} else {
foreach(var contextHandlers in commandBindingsUpdateHandlers) {
- foreach(var handler in contextHandlers.Value) {
- if(handler != null && handler.Target != null) {
- ((BindingsUpdatedHandler)handler.Target).Invoke();
+ foreach(var instanceHandlers in contextHandlers.Value) {
+ foreach(var handler in instanceHandlers.Value) {
+ if(handler != null) {
+ ((BindingsUpdatedHandler)handler).Invoke();
+ }
}
}
}
@@ -305,7 +419,6 @@ namespace ICSharpCode.Core.Presentation
}
}
-
///
/// Load context
///
@@ -322,22 +435,22 @@ namespace ICSharpCode.Core.Presentation
/// Null arguments are ignored
///
/// Context class full name
+ /// Get command bindings assigned only to specific context
/// Context class full name
/// Context class full name
/// Collection of managed command bindings
- public static CommandBindingCollection GetCommandBindings(string contextName, string routedCommandName, string className) {
+ public static CommandBindingCollection GetCommandBindings(string contextName, UIElement contextInstance, string routedCommandName, string className) {
var bindings = new CommandBindingCollection();
foreach(var binding in commandBindings) {
if((contextName == null || binding.ContextName == contextName)
+ && (contextInstance == null || binding.Context == null || binding.Context == contextInstance)
&& (routedCommandName == null || binding.RoutedCommandName == routedCommandName)
&& (className == null || binding.ClassName == className)) {
- var handlers = new CommandBindingHandlersContainer(binding);
-
var managedCommandBinding = new ManagedCommandBinding(binding.RoutedCommand);
- managedCommandBinding.CanExecute += handlers.CanExecuteHandler;
- managedCommandBinding.Executed += handlers.ExecutedHanler;
+ managedCommandBinding.CanExecute += binding.CanExecuteEventHandler;
+ managedCommandBinding.Executed += binding.ExecutedEventHandler;
bindings.Add(managedCommandBinding);
}
@@ -352,13 +465,15 @@ namespace ICSharpCode.Core.Presentation
/// Null arguments are ignored
///
/// Context class full name
+ /// Get input bindings assigned only to specific context
/// Routed UI command name
/// Gesture
- public static InputBindingCollection GetInputBindings(string contextName, string routedCommandName, InputGesture gesture) {
+ public static InputBindingCollection GetInputBindings(string contextName, UIElement contextInstance, string routedCommandName, InputGesture gesture) {
var bindings = new InputBindingCollection();
foreach(var binding in inputBidnings) {
if((contextName == null || binding.ContextName == contextName)
+ && (contextInstance == null || binding.Context == null || binding.Context == contextInstance)
&& (routedCommandName == null || binding.RoutedCommandName == routedCommandName)
&& (gesture == null || binding.Gesture == gesture)) {
@@ -369,16 +484,17 @@ namespace ICSharpCode.Core.Presentation
return bindings;
}
-///
+ ///
/// Get list of input gestures from all input bindings which satisfy provided parameters
///
/// Null arguments are ignored
///
/// Context class full name
+ /// Get gestures assigned only to specific context
/// Routed UI command name
/// Gesture
- public static InputGestureCollection GetInputGestures(string contextName, string routedCommandName, InputGesture gesture) {
- var bindings = GetInputBindings(contextName, routedCommandName, gesture);
+ public static InputGestureCollection GetInputGestures(string contextName, UIElement contextInstance, string routedCommandName, InputGesture gesture) {
+ var bindings = GetInputBindings(contextName, contextInstance, routedCommandName, gesture);
var gestures = new InputGestureCollection();
foreach(InputBinding binding in bindings) {
@@ -389,52 +505,64 @@ namespace ICSharpCode.Core.Presentation
}
///
- /// Stores Executed and CanExecute event handlers used in command bindings
+ /// Create default BindingUpdateHandler which will update command bindings in specified context
+ ///
+ /// Collection which should be updated with latest bindings
+ /// Context name which was used to register command bindings
+ /// Reference to instance which is used to find command bindings registered in specific context instance
+ /// Bindings updated handler
+ public static BindingsUpdatedHandler CreateCommandBindingUpdateHandler(CommandBindingCollection bindingsCollection, string contextName, UIElement contextInstance) {
+ return new CommonCommandBindingUpdateDelegate(bindingsCollection, contextName, contextInstance).UpdateCommandBinding;
+ }
+
+ ///
+ /// Create default BindingUpdateHandler which will update input bindings in specified context
///
- class CommandBindingHandlersContainer
+ /// Collection which should be updated with latest bindings
+ /// Context name which was used to register input bindings
+ /// Reference to instance which is used to find command bindings registered in specific context instance
+ /// Bindings updated handler
+ public static BindingsUpdatedHandler CreateInputBindingUpdateHandler(InputBindingCollection bindingsCollection, string contextName, UIElement contextInstance) {
+ return new CommonInputBindingUpdateDelegate(bindingsCollection, contextName, contextInstance).UpdateInputBinding;
+ }
+
+ class CommonCommandBindingUpdateDelegate
{
- private CommandBindingInfo binding;
+ CommandBindingCollection bindingsCollection;
+ string contextName;
+ UIElement contextInstance;
- ///
- /// Constructor
- ///
- /// Reference to object holding command bining details
- public CommandBindingHandlersContainer(CommandBindingInfo binding) {
- this.binding = binding;
- }
-
- ///
- /// CanExecute event handler
- ///
- /// Object which raised this event
- /// Event arguments
- public void CanExecuteHandler(Object sender, CanExecuteRoutedEventArgs e) {
- if(binding.IsLazy && binding.Class == null) {
- e.CanExecute = true;
- } else if(binding.Class == null) {
- e.CanExecute = false;
- } else {
- e.CanExecute = binding.Class.CanExecute(e.Parameter);
- }
+ public CommonCommandBindingUpdateDelegate(CommandBindingCollection bindingsCollection, string contextName, UIElement contextInstance) {
+ this.bindingsCollection = bindingsCollection;
+ this.contextName = contextName;
+ this.contextInstance = contextInstance;
}
- ///
- /// Executed event handler
- ///
- /// Object which raised this event
- /// Event arguments
- public void ExecutedHanler(Object sender, ExecutedRoutedEventArgs e) {
- if(binding.IsLazy && binding.Class == null) {
- binding.AddIn.LoadRuntimeAssemblies();
-
- var command = (ICommand)binding.AddIn.CreateObject(binding.ClassName);
- CommandsRegistry.LoadCommand(binding.ClassName, command);
- }
-
- if(binding.Class != null) {
- binding.Class.Execute(e.Parameter);
- }
+ public void UpdateCommandBinding() {
+ var newBindings = CommandsRegistry.GetCommandBindings(contextName, contextInstance, null, null);
+ CommandsRegistry.RemoveManagedCommandBindings(bindingsCollection);
+ bindingsCollection.AddRange(newBindings);
}
}
+
+
+ class CommonInputBindingUpdateDelegate
+ {
+ InputBindingCollection bindingsCollection;
+ string contextName;
+ UIElement contextInstance;
+
+ public CommonInputBindingUpdateDelegate(InputBindingCollection bindingsCollection, string contextName, UIElement contextInstance) {
+ this.bindingsCollection = bindingsCollection;
+ this.contextName = contextName;
+ this.contextInstance = contextInstance;
+ }
+
+ public void UpdateInputBinding() {
+ var newBindings = CommandsRegistry.GetInputBindings(contextName, contextInstance, null, null);
+ CommandsRegistry.RemoveManagedInputBindings(bindingsCollection);
+ bindingsCollection.AddRange(newBindings);
+ }
+ }
}
}
diff --git a/src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandsService.cs b/src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandsService.cs
index 6c33e823a0..26821428a7 100644
--- a/src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandsService.cs
+++ b/src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandsService.cs
@@ -11,11 +11,11 @@ namespace ICSharpCode.Core.Presentation
///
public static class CommandsService
{
- private static void RegisterRoutedCommands(Type type) {
+ public static void RegisterRoutedCommands(Type type) {
var typeProperties = type.GetProperties(BindingFlags.Static | BindingFlags.Public);
foreach(var property in typeProperties) {
var command = (RoutedUICommand)property.GetValue(null, null);
- CommandsRegistry.RegisterRoutedUICommand(type.Name + "." + command.Name, command.Text);
+ CommandsRegistry.RegisterRoutedUICommand(command);
}
}
@@ -46,13 +46,13 @@ namespace ICSharpCode.Core.Presentation
CommandsRegistry.RegisterRoutedUICommand(desc.Command, desc.Command);
}
- CommandsRegistry.RegisterCommandBinding(contextName, desc.Command, desc.Class, desc.Codon.AddIn, desc.Lazy);
+ CommandsRegistry.RegisterCommandBinding(contextName, null, desc.Command, desc.Class, desc.Codon.AddIn, desc.Lazy);
// If gestures are provided register input binding in the same context
if(!string.IsNullOrEmpty(desc.Gestures)) {
var gestures = (InputGestureCollection)new InputGestureCollectionConverter().ConvertFromString(desc.Gestures);
foreach(InputGesture gesture in gestures) {
- CommandsRegistry.RegisterInputBinding(contextName, desc.Command, gesture);
+ CommandsRegistry.RegisterInputBinding(contextName, null, desc.Command, gesture);
}
}
}
@@ -65,7 +65,7 @@ namespace ICSharpCode.Core.Presentation
var contextName = !string.IsNullOrEmpty(desc.Context) ? desc.Context : CommandsRegistry.DefaultContext;
var gesture = (KeyGesture)new KeyGestureConverter().ConvertFromInvariantString(desc.Gesture);
- CommandsRegistry.RegisterInputBinding(contextName, desc.Command, gesture);
+ CommandsRegistry.RegisterInputBinding(contextName, null, desc.Command, gesture);
}
}
}
diff --git a/src/Main/ICSharpCode.Core.Presentation/CommandsService/InputBindingInfo.cs b/src/Main/ICSharpCode.Core.Presentation/CommandsService/InputBindingInfo.cs
index b80765dc8c..229aaaaf1d 100644
--- a/src/Main/ICSharpCode.Core.Presentation/CommandsService/InputBindingInfo.cs
+++ b/src/Main/ICSharpCode.Core.Presentation/CommandsService/InputBindingInfo.cs
@@ -9,6 +9,8 @@ namespace ICSharpCode.Core.Presentation
///
public class InputBindingInfo
{
+ private UIElement contextInstance;
+
///
/// Constructor
///
@@ -21,6 +23,14 @@ namespace ICSharpCode.Core.Presentation
Gesture = gesture;
}
+ public InputBindingInfo(string contextName, UIElement contextInstance, string routedCommandName, InputGesture gesture) {
+ ContextName = contextName;
+ RoutedCommandName = routedCommandName;
+ Gesture = gesture;
+ this.contextInstance = contextInstance;
+ }
+
+
///
/// Context class full name
///
@@ -37,10 +47,14 @@ namespace ICSharpCode.Core.Presentation
///
public UIElement Context {
get {
- UIElement context;
- CommandsRegistry.contexts.TryGetValue(ContextName, out context);
-
- return context;
+ if(contextInstance != null) {
+ return contextInstance;
+ } else {
+ UIElement context;
+ CommandsRegistry.contexts.TryGetValue(ContextName, out context);
+
+ return context;
+ }
}
}
diff --git a/src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs b/src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs
index 43c2a6b5e9..29f1138f5e 100644
--- a/src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs
+++ b/src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs
@@ -127,9 +127,9 @@ namespace ICSharpCode.Core.Presentation
} else {
this.Command = routedCommand;
- var gestures = CommandsRegistry.GetInputGestures(CommandsRegistry.DefaultContext, routedCommand.Name, null);
+ var gestures = CommandsRegistry.GetInputGestures(CommandsRegistry.DefaultContext, null, routedCommand.Name, null);
var gesturesString = (string)new InputGestureCollectionConverter().ConvertToInvariantString(gestures);
- this.InputGestureText = "M: " + gesturesString;
+ this.InputGestureText = gesturesString;
}
} else {
this.Command = CommandWrapper.GetCommand(codon, caller, createCommand);