Browse Source

Fix exceptions when opening new pad from view menu

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@4173 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts^2
Sergej Andrejev 16 years ago
parent
commit
e451c17012
  1. 8
      AddIns/ICSharpCode.SharpDevelop.addin
  2. 12
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs
  3. 41
      src/Main/Base/Project/Src/Commands/MenuItemBuilders.cs
  4. 17
      src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonPadContent.cs
  5. 20
      src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonWorkbenchWindow.cs
  6. 18
      src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs
  7. 71
      src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandBindingInfo.cs
  8. 312
      src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandsRegistry.cs
  9. 10
      src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandsService.cs
  10. 22
      src/Main/ICSharpCode.Core.Presentation/CommandsService/InputBindingInfo.cs
  11. 4
      src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs

8
AddIns/ICSharpCode.SharpDevelop.addin

@ -52,7 +52,6 @@
</Runtime> </Runtime>
<!-- Commands registry test
<Path name="/SharpDevelop/Workbench/RoutedUICommands"> <Path name="/SharpDevelop/Workbench/RoutedUICommands">
<RoutedUICommand name="SDTestCommands.Test" text="Create new file" /> <RoutedUICommand name="SDTestCommands.Test" text="Create new file" />
@ -65,8 +64,6 @@
<RoutedUICommand name="SDBuildCommands.AbortBuild" text="${res:XML.MainMenu.BuildMenu.AbortBuild}" /> <RoutedUICommand name="SDBuildCommands.AbortBuild" text="${res:XML.MainMenu.BuildMenu.AbortBuild}" />
<RoutedUICommand name="SDBuildCommands.EditConfigurationsCommand" text="${res:XML.MainMenu.BuildMenu.EditConfigurationsPlatforms}" /> <RoutedUICommand name="SDBuildCommands.EditConfigurationsCommand" text="${res:XML.MainMenu.BuildMenu.EditConfigurationsPlatforms}" />
<RoutedUICommand name="SDWindowCommands.SplitView" text="TODO: Split view" />
<RoutedUICommand name="SDProjectCommands.AddNewProjectToSolution" text="${res:ProjectComponent.ContextMenu.NewProject}" /> <RoutedUICommand name="SDProjectCommands.AddNewProjectToSolution" text="${res:ProjectComponent.ContextMenu.NewProject}" />
<RoutedUICommand name="SDProjectCommands.AddExitingProjectToSolution" text="${res:ProjectComponent.ContextMenu.ExistingProject}" /> <RoutedUICommand name="SDProjectCommands.AddExitingProjectToSolution" text="${res:ProjectComponent.ContextMenu.ExistingProject}" />
<RoutedUICommand name="SDProjectCommands.AddExistingItemToSolution" text="${res:ProjectComponent.ContextMenu.AddItem}" /> <RoutedUICommand name="SDProjectCommands.AddExistingItemToSolution" text="${res:ProjectComponent.ContextMenu.AddItem}" />
@ -96,8 +93,10 @@
<RoutedUICommand name="SDSearchCommands.ClearBookmarks" text="${res:XML.MainMenu.SearchMenu.ClearBookmarks}" /> <RoutedUICommand name="SDSearchCommands.ClearBookmarks" text="${res:XML.MainMenu.SearchMenu.ClearBookmarks}" />
<RoutedUICommand name="SDSearchCommands.GotoLineNumber" text="${res:XML.MainMenu.SearchMenu.GotoLineNr}" /> <RoutedUICommand name="SDSearchCommands.GotoLineNumber" text="${res:XML.MainMenu.SearchMenu.GotoLineNr}" />
<RoutedUICommand name="SDSearchCommands.GotoBrace" text="${res:XML.MainMenu.SearchMenu.GotoBrace}" /> <RoutedUICommand name="SDSearchCommands.GotoBrace" text="${res:XML.MainMenu.SearchMenu.GotoBrace}" />
<RoutedUICommand name="SDWindowCommands.SplitView" text="Split view" />
</Path> </Path>
-->
<Path name="/SharpDevelop/Workbench/CommandBindings"> <Path name="/SharpDevelop/Workbench/CommandBindings">
<CommandBinding command="SDTestCommands.Test" class="ICSharpCode.SharpDevelop.Commands.TestCommand" gestures="Ctrl+M" /> <CommandBinding command="SDTestCommands.Test" class="ICSharpCode.SharpDevelop.Commands.TestCommand" gestures="Ctrl+M" />
@ -136,7 +135,6 @@
<CommandBinding command="SDSearchCommands.ClearBookmarks" class="ICSharpCode.SharpDevelop.Bookmarks.ClearBookmarks" /> <CommandBinding command="SDSearchCommands.ClearBookmarks" class="ICSharpCode.SharpDevelop.Bookmarks.ClearBookmarks" />
<CommandBinding command="SDSearchCommands.GotoLineNumber" class="ICSharpCode.SharpDevelop.DefaultEditor.Commands.GotoLineNumber" gestures="Ctrl+G" /> <CommandBinding command="SDSearchCommands.GotoLineNumber" class="ICSharpCode.SharpDevelop.DefaultEditor.Commands.GotoLineNumber" gestures="Ctrl+G" />
<CommandBinding command="SDSearchCommands.GotoBrace" class="ICSharpCode.SharpDevelop.DefaultEditor.Commands.GotoMatchingBrace" gestures="Ctrl+B" /> <CommandBinding command="SDSearchCommands.GotoBrace" class="ICSharpCode.SharpDevelop.DefaultEditor.Commands.GotoMatchingBrace" gestures="Ctrl+B" />
</Path> </Path>
<Path name="/SharpDevelop/Workbench/InputBindings"> <Path name="/SharpDevelop/Workbench/InputBindings">

12
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs

@ -117,7 +117,13 @@ namespace ICSharpCode.AvalonEdit.AddIn
public CodeEditor() 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); textMarkerService = new TextMarkerService(this);
iconBarManager = new IconBarManager(); iconBarManager = new IconBarManager();
@ -198,6 +204,10 @@ namespace ICSharpCode.AvalonEdit.AddIn
primaryTextEditor.Save(stream); primaryTextEditor.Save(stream);
} }
void OnCanSplitView(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
void OnSplitView(object sender, ExecutedRoutedEventArgs e) void OnSplitView(object sender, ExecutedRoutedEventArgs e)
{ {
if (secondaryTextEditor == null) { if (secondaryTextEditor == null) {

41
src/Main/Base/Project/Src/Commands/MenuItemBuilders.cs

@ -456,6 +456,8 @@ namespace ICSharpCode.SharpDevelop.Commands
get; get;
} }
public List<string> bindingsAssigned = new List<string>();
public ICollection BuildItems(Codon codon, object owner) public ICollection BuildItems(Codon codon, object owner)
{ {
ArrayList list = new ArrayList(); ArrayList list = new ArrayList();
@ -467,33 +469,32 @@ namespace ICSharpCode.SharpDevelop.Commands
item.Icon = PresentationResourceService.GetPixelSnappedImage(padContent.Icon); item.Icon = PresentationResourceService.GetPixelSnappedImage(padContent.Icon);
} }
// Dynamicaly create routed UI command for loaded pad
var routedCommandName = "SDViewCommands.ShowView_" + padContent.Class; var routedCommandName = "SDViewCommands.ShowView_" + padContent.Class;
var routedCommandText = "Show view " + MenuService.ConvertLabel(StringParser.Parse(padContent.Title)); 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 // TODO: fix this hack
if (!string.IsNullOrEmpty(padContent.Shortcut)) { if(!bindingsAssigned.Contains(routedCommandName)) {
var gestures = (InputGestureCollection)new InputGestureCollectionConverter().ConvertFromString(padContent.Shortcut); // Dynamicaly create routed UI command to loaded pad and bindings for it
foreach(InputGesture gesture in gestures) { CommandsRegistry.RegisterRoutedUICommand(routedCommandName, routedCommandText);
CommandsRegistry.RegisterInputBinding(CommandsRegistry.DefaultContext, routedCommandName, gesture); 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; bindingsAssigned.Add(routedCommandName);
} else {
item.InputGestureText = "M: ";
} }
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); // item.Command = new BringPadToFrontCommand(padContent);
// if (!string.IsNullOrEmpty(padContent.Shortcut)) { // if (!string.IsNullOrEmpty(padContent.Shortcut)) {

17
src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonPadContent.cs

@ -91,19 +91,10 @@ namespace ICSharpCode.SharpDevelop.Gui
CommandsRegistry.LoadContext(contextName, (UIElement)Content); CommandsRegistry.LoadContext(contextName, (UIElement)Content);
CommandsRegistry.RegisterCommandBindingsUpdateHandler(contextName, delegate { CommandsRegistry.RegisterCommandBindingsUpdateHandler(contextName, null, CommandsRegistry.CreateCommandBindingUpdateHandler(CommandBindings, contextName, null));
var bindings = CommandsRegistry.GetCommandBindings(contextName, null, null); CommandsRegistry.RegisterInputBindingUpdateHandler(contextName, null, CommandsRegistry.CreateInputBindingUpdateHandler(InputBindings, contextName, null));
CommandsRegistry.RemoveManagedCommandBindings(CommandBindings); CommandsRegistry.InvokeCommandBindingUpdateHandlers(contextName, null);
CommandBindings.AddRange(bindings); CommandsRegistry.InvokeInputBindingUpdateHandlers(contextName, null);
});
CommandsRegistry.RegisterInputBindingUpdateHandler(contextName, delegate {
var bindings = CommandsRegistry.GetInputBindings(contextName, null, null);
CommandsRegistry.RemoveManagedInputBindings(InputBindings);
InputBindings.AddRange(bindings);
});
CommandsRegistry.InvokeCommandBindingUpdateHandlers(contextName);
CommandsRegistry.InvokeInputBindingUpdateHandlers(contextName);
} }
} }
} }

20
src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonWorkbenchWindow.cs

@ -97,23 +97,11 @@ namespace ICSharpCode.SharpDevelop.Gui
CommandsRegistry.LoadContext(contextName, (UIElement)Content); CommandsRegistry.LoadContext(contextName, (UIElement)Content);
CommandsRegistry.RegisterCommandBindingsUpdateHandler(
contextName,
delegate {
var bindings = CommandsRegistry.GetCommandBindings(contextName, null, null);
CommandsRegistry.RemoveManagedCommandBindings(CommandBindings);
CommandBindings.AddRange(bindings);
});
CommandsRegistry.RegisterInputBindingUpdateHandler( CommandsRegistry.RegisterCommandBindingsUpdateHandler(contextName, null, CommandsRegistry.CreateCommandBindingUpdateHandler(CommandBindings, contextName, null));
contextName, CommandsRegistry.RegisterInputBindingUpdateHandler(contextName, null, CommandsRegistry.CreateInputBindingUpdateHandler(InputBindings, contextName, null));
delegate { CommandsRegistry.InvokeCommandBindingUpdateHandlers(contextName, null);
var bindings = CommandsRegistry.GetInputBindings(contextName, null, null); CommandsRegistry.InvokeInputBindingUpdateHandlers(contextName, null);
CommandsRegistry.RemoveManagedInputBindings(InputBindings);
InputBindings.AddRange(bindings);
});
CommandsRegistry.InvokeCommandBindingUpdateHandlers(contextName);
CommandsRegistry.InvokeInputBindingUpdateHandlers(contextName);
} }
} }

18
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 // Register context and load all commands from addin
CommandsRegistry.LoadAddinCommands(AddInTree.AddIns.FirstOrDefault(a => a.Name == "SharpDevelop")); CommandsRegistry.LoadAddinCommands(AddInTree.AddIns.FirstOrDefault(a => a.Name == "SharpDevelop"));
CommandsRegistry.RegisterCommandBindingsUpdateHandler(CommandsRegistry.DefaultContext, delegate { CommandsRegistry.RegisterCommandBindingsUpdateHandler(CommandsRegistry.DefaultContext, null, CommandsRegistry.CreateCommandBindingUpdateHandler(CommandBindings, CommandsRegistry.DefaultContext, null));
var bindings = CommandsRegistry.GetCommandBindings(CommandsRegistry.DefaultContext, null, null); CommandsRegistry.RegisterInputBindingUpdateHandler(CommandsRegistry.DefaultContext, null, CommandsRegistry.CreateInputBindingUpdateHandler(InputBindings, CommandsRegistry.DefaultContext, null));
CommandsRegistry.RemoveManagedCommandBindings(CommandBindings); CommandsRegistry.InvokeCommandBindingUpdateHandlers(CommandsRegistry.DefaultContext, null);
CommandBindings.AddRange(bindings); CommandsRegistry.InvokeInputBindingUpdateHandlers(CommandsRegistry.DefaultContext, null);
});
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);
mainMenu.ItemsSource = MenuService.CreateMenuItems(this, this, mainMenuPath); mainMenu.ItemsSource = MenuService.CreateMenuItems(this, this, mainMenuPath);

71
src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandBindingInfo.cs

@ -9,6 +9,8 @@ namespace ICSharpCode.Core.Presentation
/// </summary> /// </summary>
public class CommandBindingInfo public class CommandBindingInfo
{ {
private UIElement contextInstance;
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
@ -24,6 +26,30 @@ namespace ICSharpCode.Core.Presentation
IsLazy = isLazy; IsLazy = isLazy;
AddIn = addIn; 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;
}
/// <summary> /// <summary>
/// Routed command name /// Routed command name
@ -101,10 +127,14 @@ namespace ICSharpCode.Core.Presentation
/// </summary> /// </summary>
public UIElement Context { public UIElement Context {
get { get {
UIElement context; if(contextInstance != null) {
CommandsRegistry.contexts.TryGetValue(ContextName, out context); return contextInstance;
} else {
return context; UIElement context;
CommandsRegistry.contexts.TryGetValue(ContextName, out context);
return context;
}
} }
} }
@ -118,5 +148,38 @@ namespace ICSharpCode.Core.Presentation
public bool IsLazy{ public bool IsLazy{
get; private set; 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);
}
}
}
} }
} }

312
src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandsRegistry.cs

@ -14,6 +14,11 @@ namespace ICSharpCode.Core.Presentation
/// </summary> /// </summary>
public static class CommandsRegistry public static class CommandsRegistry
{ {
/// <summary>
/// This element is used to represent null key in dictionary
/// </summary>
private static UIElement NullUIElement = new UIElement();
/// <summary> /// <summary>
/// Default application context. /// Default application context.
/// ///
@ -30,8 +35,8 @@ namespace ICSharpCode.Core.Presentation
internal static Dictionary<string, System.Windows.Input.ICommand> commands = new Dictionary<string, System.Windows.Input.ICommand>(); internal static Dictionary<string, System.Windows.Input.ICommand> commands = new Dictionary<string, System.Windows.Input.ICommand>();
internal static Dictionary<string, UIElement> contexts = new Dictionary<string, UIElement>(); internal static Dictionary<string, UIElement> contexts = new Dictionary<string, UIElement>();
private static Dictionary<string, List<WeakReference>> commandBindingsUpdateHandlers = new Dictionary<string, List<WeakReference>>(); private static Dictionary<string, Dictionary<UIElement, List<BindingsUpdatedHandler>>> commandBindingsUpdateHandlers = new Dictionary<string, Dictionary<UIElement, List<BindingsUpdatedHandler>>>();
private static Dictionary<string, List<WeakReference>> inputBindingsUpdateHandlers = new Dictionary<string, List<WeakReference>>(); private static Dictionary<string, Dictionary<UIElement, List<BindingsUpdatedHandler>>> inputBindingsUpdateHandlers = new Dictionary<string, Dictionary<UIElement, List<BindingsUpdatedHandler>>>();
/// <summary> /// <summary>
/// Get reference to routed UI command by name /// Get reference to routed UI command by name
@ -45,20 +50,48 @@ namespace ICSharpCode.Core.Presentation
return null; return null;
} }
/// <summary>
/// Checks whether routed UI command registered
/// </summary>
/// <param name="routedCommandName">Routed command name</param>
/// <returns>Returns value specifting whether routed UI command is registered</returns>
public static bool IsRoutedUICommandRegistered(string routedCommandName) {
return GetRoutedUICommand(routedCommandName) != null;
}
/// <summary> /// <summary>
/// Register new routed command in the global registry /// Register new routed command in the global registry
/// ///
/// Routed command name should be uniq in SharpDevelop scope. /// Routed command name should be unique in SharpDevelop scope.
/// Use "." to emulate namespaces /// Use "." to organize commands into groups
/// </summary> /// </summary>
/// <param name="routedCommandName">Routed command name</param> /// <param name="routedCommandName">Routed command name</param>
/// <param name="text">Short text describing command functionality</param> /// <param name="text">Short text describing command functionality</param>
public static void RegisterRoutedUICommand(string routedCommandName, string text) { 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)) { if(!routedCommands.ContainsKey(routedCommandName)) {
routedCommands.Add(routedCommandName, routedCommand); routedCommands.Add(routedCommandName, routedCommand);
} else {
var test = routedCommands[routedCommandName];
throw new IndexOutOfRangeException("Routed UI command with name " + routedCommandName + " is already registered");
}
}
/// <summary>
/// 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
/// </summary>
/// <param name="routedCommandName">Existing routed command</param>
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 { } else {
throw new IndexOutOfRangeException("Routed UI command with name " + routedCommandName + " is already registered"); throw new IndexOutOfRangeException("Routed UI command with name " + routedCommandName + " is already registered");
} }
@ -75,16 +108,17 @@ namespace ICSharpCode.Core.Presentation
} }
/// <summary> /// <summary>
/// Register several input bindings with the same /// Register input binding in context
/// ///
/// Registering input binding means that when provided gesture is met in specified /// Registering input binding means that when specified gesture is met in specified
/// context routed command will be invoked /// context routed command is invoked
/// </summary> /// </summary>
/// <param name="contextName">Context class full name</param> /// <param name="contextName">Context class full name</param>
/// <param name="contextInstance">Context class instance. If instance is provided this input binding only applies to provided UI element</param>
/// <param name="routedCommandName">Routed UI command invoked on gesture run</param> /// <param name="routedCommandName">Routed UI command invoked on gesture run</param>
/// <param name="gesture">Gesture</param> /// <param name="gesture">Gesture</param>
public static void RegisterInputBinding(string contextName, string routedCommandName, InputGesture gesture) { public static void RegisterInputBinding(string contextName, UIElement contextInstance, string routedCommandName, InputGesture gesture) {
var inputBindingInfo = new InputBindingInfo(contextName, routedCommandName, gesture); var inputBindingInfo = new InputBindingInfo(contextName, contextInstance, routedCommandName, gesture);
inputBidnings.Add(inputBindingInfo); inputBidnings.Add(inputBindingInfo);
} }
@ -94,11 +128,13 @@ namespace ICSharpCode.Core.Presentation
/// Null arguments are ignored /// Null arguments are ignored
/// </summary> /// </summary>
/// <param name="contextName">Context class full name</param> /// <param name="contextName">Context class full name</param>
/// <param name="contextInstance">Unregister binding assigned to specific context instance</param>
/// <param name="routedCommandName">Routed UI command name</param> /// <param name="routedCommandName">Routed UI command name</param>
/// <param name="gesture">Gesture</param> /// <param name="gesture">Gesture</param>
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--) { for(int i = inputBidnings.Count - 1; i >= 0; i--) {
if((contextName == null || inputBidnings[i].ContextName == contextName) if((contextName == null || inputBidnings[i].ContextName == contextName)
&& (contextInstance == null || inputBidnings[i].Context == null || inputBidnings[i].Context == contextInstance)
&& (routedCommandName == null || inputBidnings[i].RoutedCommandName == routedCommandName) && (routedCommandName == null || inputBidnings[i].RoutedCommandName == routedCommandName)
&& (gesture == null || inputBidnings[i].Gesture == gesture)) { && (gesture == null || inputBidnings[i].Gesture == gesture)) {
inputBidnings.RemoveAt(i); 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 /// Register delegate which will be invoked on change in input bindings in specified context
/// </summary> /// </summary>
/// <param name="contextName">Context class full name</param> /// <param name="contextName">Context class full name</param>
/// <param name="contextInstance">Register update handler which will trigger only if input bindings registered for this object where triggered</param>
/// <param name="handler">Update handler delegate</param> /// <param name="handler">Update handler delegate</param>
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)) { if(!inputBindingsUpdateHandlers.ContainsKey(contextName)) {
inputBindingsUpdateHandlers.Add(contextName, new List<WeakReference>()); inputBindingsUpdateHandlers.Add(contextName, new Dictionary<UIElement, List<BindingsUpdatedHandler>>());
} }
inputBindingsUpdateHandlers[contextName].Add(new WeakReference(handler)); if(!inputBindingsUpdateHandlers[contextName].ContainsKey(contextInstance)) {
inputBindingsUpdateHandlers[contextName].Add(contextInstance, new List<BindingsUpdatedHandler>());
}
inputBindingsUpdateHandlers[contextName][contextInstance].Add(handler);
} }
/// <summary> /// <summary>
/// Remove input bindings update handler /// Remove input bindings update handler
/// </summary> /// </summary>
/// <param name="contextName">Context class full name</param> /// <param name="contextName">Context class full name</param>
/// <param name="contextInstance">Unregister update handler which was triggered only if input bindings registered for specific instance where updated</param>
/// <param name="handler">Update handler delegate</param> /// <param name="handler">Update handler delegate</param>
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)) { if(!inputBindingsUpdateHandlers.ContainsKey(contextName)) {
for(int i = inputBindingsUpdateHandlers[contextName].Count - 1; i >= 0; i++) { if(!inputBindingsUpdateHandlers[contextName].ContainsKey(contextInstance)) {
if(inputBindingsUpdateHandlers[contextName][i].Target == handler) { for(int i = inputBindingsUpdateHandlers[contextName][contextInstance].Count - 1; i >= 0; i++) {
inputBindingsUpdateHandlers[contextName].RemoveAt(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 /// Invoke registered input bindings update handlers registered in specified context
/// </summary> /// </summary>
/// <param name="contextName">Context class full name</param> /// <param name="contextName">Context class full name</param>
public static void InvokeInputBindingUpdateHandlers(string contextName) { public static void InvokeInputBindingUpdateHandlers(string contextName, UIElement contextInstance) {
if(contextInstance == null) {
contextInstance = NullUIElement;
}
if(contextName != null) { if(contextName != null) {
if(inputBindingsUpdateHandlers.ContainsKey(contextName)) { if(inputBindingsUpdateHandlers.ContainsKey(contextName)) {
foreach(var handler in inputBindingsUpdateHandlers[contextName]) { if(contextInstance == NullUIElement) {
if(handler != null && handler.Target != null) { foreach(var instanceHandlers in inputBindingsUpdateHandlers[contextName]) {
((BindingsUpdatedHandler)handler.Target).Invoke(); 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 { } else {
foreach(var contextHandlers in inputBindingsUpdateHandlers) { foreach(var contextHandlers in inputBindingsUpdateHandlers) {
foreach(var handler in contextHandlers.Value) { foreach(var instanceHandlers in contextHandlers.Value) {
if(handler != null && handler.Target != null) { foreach(var handler in instanceHandlers.Value) {
((BindingsUpdatedHandler)handler.Target).Invoke(); 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) /// in specified context event is routed to specified command (implementing ICommand class)
/// </summary> /// </summary>
/// <param name="contextName">Context class full name</param> /// <param name="contextName">Context class full name</param>
/// <param name="contextInstance">Register update handler which is triggered only if input bindings registered for specific instance are updated</param>
/// <param name="routedCommandName">Routed UI command name</param> /// <param name="routedCommandName">Routed UI command name</param>
/// <param name="className">Command full name to which invokation event is routed</param> /// <param name="className">Command full name to which invokation event is routed</param>
/// <param name="addIn">Add-in in which hosts the command</param> /// <param name="addIn">Add-in in which hosts the command</param>
/// <param name="isLazy">Load add-in referenced assemblies on command invocation</param> /// <param name="isLazy">Load add-in referenced assemblies on command invocation</param>
public static void RegisterCommandBinding(string contextName, string routedCommandName, string className, AddIn addIn, bool isLazy) { public static void RegisterCommandBinding(string contextName, UIElement contextInstance, string routedCommandName, string className, AddIn addIn, bool isLazy) {
var commandBindingInfo = new CommandBindingInfo(contextName, routedCommandName, className, addIn, isLazy); var commandBindingInfo = new CommandBindingInfo(contextName, contextInstance, routedCommandName, className, addIn, isLazy);
commandBindings.Add(commandBindingInfo);
}
/// <summary>
/// Register command binding which when triggered provided delegates are invoked
/// </summary>
/// <param name="contextName">Context class full name</param>
/// <param name="contextInstance">Register update handler which is triggered only if input bindings registered for specific instance are updated</param>
/// <param name="routedCommandName">Routed UI command name</param>
/// <param name="executedEventHandler">Delegate which is called when binding is triggered</param>
/// <param name="canExecuteEventHandler">Delegate which is called to check whether executedEventHandler can be invoked</param>
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); commandBindings.Add(commandBindingInfo);
} }
@ -193,11 +274,13 @@ namespace ICSharpCode.Core.Presentation
/// Null arguments are ignored /// Null arguments are ignored
/// </summary> /// </summary>
/// <param name="contextName">Context class full name</param> /// <param name="contextName">Context class full name</param>
/// <param name="contextInstance">Unregister update handler which was triggered only if command bindings registered for specific instance where updated</param>
/// <param name="routedCommandName">Routed UI command name</param> /// <param name="routedCommandName">Routed UI command name</param>
/// <param name="className">Command full name to which invokation event is routed</param> /// <param name="className">Command full name to which invokation event is routed</param>
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--) { for(int i = commandBindings.Count - 1; i >= 0; i--) {
if((contextName == null || commandBindings[i].ContextName == contextName) if((contextName == null || commandBindings[i].ContextName == contextName)
&& (contextInstance == null || commandBindings[i].Context == null || commandBindings[i].Context == contextInstance)
&& (routedCommandName == null || commandBindings[i].RoutedCommandName == routedCommandName) && (routedCommandName == null || commandBindings[i].RoutedCommandName == routedCommandName)
&& (className == null || commandBindings[i].ClassName == className)) { && (className == null || commandBindings[i].ClassName == className)) {
inputBidnings.RemoveAt(i); 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 /// Register delegate which will be invoked on any chage in command bindings of specified context
/// </summary> /// </summary>
/// <param name="contextName">Context class full name</param> /// <param name="contextName">Context class full name</param>
/// <param name="contextInstance">Register update handler which is triggered only if input bindings registered for specific instance are updated</param>
/// <param name="handler">Update handler delegate</param> /// <param name="handler">Update handler delegate</param>
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)) { if(!commandBindingsUpdateHandlers.ContainsKey(contextName)) {
commandBindingsUpdateHandlers.Add(contextName, new List<WeakReference>()); commandBindingsUpdateHandlers.Add(contextName, new Dictionary<UIElement, List<BindingsUpdatedHandler>>());
}
if(!commandBindingsUpdateHandlers[contextName].ContainsKey(contextInstance)) {
commandBindingsUpdateHandlers[contextName].Add(contextInstance, new List<BindingsUpdatedHandler>());
} }
commandBindingsUpdateHandlers[contextName].Add(new WeakReference(handler)); commandBindingsUpdateHandlers[contextName][contextInstance].Add(handler);
} }
/// <summary> /// <summary>
/// Remove handler command bindings update handler /// Remove handler command bindings update handler
/// </summary> /// </summary>
/// <param name="contextName">Context class full name</param> /// <param name="contextName">Context class full name</param>
/// <param name="contextInstance">Unregister update handler which was triggered only if input bindings registered for specific instance were updated</param>
/// <param name="handler">Update handler delegate</param> /// <param name="handler">Update handler delegate</param>
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)) { if(commandBindingsUpdateHandlers.ContainsKey(contextName)) {
for(int i = commandBindingsUpdateHandlers[contextName].Count - 1; i >= 0; i--) { if(commandBindingsUpdateHandlers[contextName].ContainsKey(contextInstance)) {
if(commandBindingsUpdateHandlers[contextName][i].Target == handler) { for(int i = commandBindingsUpdateHandlers[contextName][contextInstance].Count - 1; i >= 0; i--) {
commandBindingsUpdateHandlers[contextName].RemoveAt(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 /// Invoke registered command bindings update handlers registered in specified context
/// </summary> /// </summary>
/// <param name="contextName">Context class full name</param> /// <param name="contextName">Context class full name</param>
public static void InvokeCommandBindingUpdateHandlers(string contextName) { /// <param name="contextInstance">Invoke update handlers which handle update only in specifyc context</param>
public static void InvokeCommandBindingUpdateHandlers(string contextName, UIElement contextInstance) {
if(contextInstance == null) {
contextInstance = NullUIElement;
}
if(contextName != null) { if(contextName != null) {
if(commandBindingsUpdateHandlers.ContainsKey(contextName)) { if(commandBindingsUpdateHandlers.ContainsKey(contextName)) {
foreach(var handler in commandBindingsUpdateHandlers[contextName]) { if(contextInstance == NullUIElement) {
if(handler != null && handler.Target != null) { foreach(var instanceHandlers in commandBindingsUpdateHandlers[contextName]) {
((BindingsUpdatedHandler)handler.Target).Invoke(); 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 { } else {
foreach(var contextHandlers in commandBindingsUpdateHandlers) { foreach(var contextHandlers in commandBindingsUpdateHandlers) {
foreach(var handler in contextHandlers.Value) { foreach(var instanceHandlers in contextHandlers.Value) {
if(handler != null && handler.Target != null) { foreach(var handler in instanceHandlers.Value) {
((BindingsUpdatedHandler)handler.Target).Invoke(); if(handler != null) {
((BindingsUpdatedHandler)handler).Invoke();
}
} }
} }
} }
@ -305,7 +419,6 @@ namespace ICSharpCode.Core.Presentation
} }
} }
/// <summary> /// <summary>
/// Load context /// Load context
/// </summary> /// </summary>
@ -322,22 +435,22 @@ namespace ICSharpCode.Core.Presentation
/// Null arguments are ignored /// Null arguments are ignored
/// </summary> /// </summary>
/// <param name="contextName">Context class full name</param> /// <param name="contextName">Context class full name</param>
/// <param name="contextInstance">Get command bindings assigned only to specific context</param>
/// <param name="routedCommandName">Context class full name</param> /// <param name="routedCommandName">Context class full name</param>
/// <param name="className">Context class full name</param> /// <param name="className">Context class full name</param>
/// <returns>Collection of managed command bindings</returns> /// <returns>Collection of managed command bindings</returns>
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(); var bindings = new CommandBindingCollection();
foreach(var binding in commandBindings) { foreach(var binding in commandBindings) {
if((contextName == null || binding.ContextName == contextName) if((contextName == null || binding.ContextName == contextName)
&& (contextInstance == null || binding.Context == null || binding.Context == contextInstance)
&& (routedCommandName == null || binding.RoutedCommandName == routedCommandName) && (routedCommandName == null || binding.RoutedCommandName == routedCommandName)
&& (className == null || binding.ClassName == className)) { && (className == null || binding.ClassName == className)) {
var handlers = new CommandBindingHandlersContainer(binding);
var managedCommandBinding = new ManagedCommandBinding(binding.RoutedCommand); var managedCommandBinding = new ManagedCommandBinding(binding.RoutedCommand);
managedCommandBinding.CanExecute += handlers.CanExecuteHandler; managedCommandBinding.CanExecute += binding.CanExecuteEventHandler;
managedCommandBinding.Executed += handlers.ExecutedHanler; managedCommandBinding.Executed += binding.ExecutedEventHandler;
bindings.Add(managedCommandBinding); bindings.Add(managedCommandBinding);
} }
@ -352,13 +465,15 @@ namespace ICSharpCode.Core.Presentation
/// Null arguments are ignored /// Null arguments are ignored
/// </summary> /// </summary>
/// <param name="contextName">Context class full name</param> /// <param name="contextName">Context class full name</param>
/// <param name="contextInstance">Get input bindings assigned only to specific context</param>
/// <param name="routedCommandName">Routed UI command name</param> /// <param name="routedCommandName">Routed UI command name</param>
/// <param name="gesture">Gesture</param> /// <param name="gesture">Gesture</param>
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(); var bindings = new InputBindingCollection();
foreach(var binding in inputBidnings) { foreach(var binding in inputBidnings) {
if((contextName == null || binding.ContextName == contextName) if((contextName == null || binding.ContextName == contextName)
&& (contextInstance == null || binding.Context == null || binding.Context == contextInstance)
&& (routedCommandName == null || binding.RoutedCommandName == routedCommandName) && (routedCommandName == null || binding.RoutedCommandName == routedCommandName)
&& (gesture == null || binding.Gesture == gesture)) { && (gesture == null || binding.Gesture == gesture)) {
@ -369,16 +484,17 @@ namespace ICSharpCode.Core.Presentation
return bindings; return bindings;
} }
/// <summary> /// <summary>
/// Get list of input gestures from all input bindings which satisfy provided parameters /// Get list of input gestures from all input bindings which satisfy provided parameters
/// ///
/// Null arguments are ignored /// Null arguments are ignored
/// </summary> /// </summary>
/// <param name="contextName">Context class full name</param> /// <param name="contextName">Context class full name</param>
/// <param name="contextInstance">Get gestures assigned only to specific context</param>
/// <param name="routedCommandName">Routed UI command name</param> /// <param name="routedCommandName">Routed UI command name</param>
/// <param name="gesture">Gesture</param> /// <param name="gesture">Gesture</param>
public static InputGestureCollection GetInputGestures(string contextName, string routedCommandName, InputGesture gesture) { public static InputGestureCollection GetInputGestures(string contextName, UIElement contextInstance, string routedCommandName, InputGesture gesture) {
var bindings = GetInputBindings(contextName, routedCommandName, gesture); var bindings = GetInputBindings(contextName, contextInstance, routedCommandName, gesture);
var gestures = new InputGestureCollection(); var gestures = new InputGestureCollection();
foreach(InputBinding binding in bindings) { foreach(InputBinding binding in bindings) {
@ -389,52 +505,64 @@ namespace ICSharpCode.Core.Presentation
} }
/// <summary> /// <summary>
/// Stores Executed and CanExecute event handlers used in command bindings /// Create default BindingUpdateHandler which will update command bindings in specified context
/// </summary>
/// <param name="bindingsCollection">Collection which should be updated with latest bindings</param>
/// <param name="contextName">Context name which was used to register command bindings</param>
/// <param name="contextInstance">Reference to instance which is used to find command bindings registered in specific context instance</param>
/// <returns>Bindings updated handler</returns>
public static BindingsUpdatedHandler CreateCommandBindingUpdateHandler(CommandBindingCollection bindingsCollection, string contextName, UIElement contextInstance) {
return new CommonCommandBindingUpdateDelegate(bindingsCollection, contextName, contextInstance).UpdateCommandBinding;
}
/// <summary>
/// Create default BindingUpdateHandler which will update input bindings in specified context
/// </summary> /// </summary>
class CommandBindingHandlersContainer /// <param name="bindingsCollection">Collection which should be updated with latest bindings</param>
/// <param name="contextName">Context name which was used to register input bindings</param>
/// <param name="contextInstance">Reference to instance which is used to find command bindings registered in specific context instance</param>
/// <returns>Bindings updated handler</returns>
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;
/// <summary> public CommonCommandBindingUpdateDelegate(CommandBindingCollection bindingsCollection, string contextName, UIElement contextInstance) {
/// Constructor this.bindingsCollection = bindingsCollection;
/// </summary> this.contextName = contextName;
/// <param name="binding">Reference to object holding command bining details</param> this.contextInstance = contextInstance;
public CommandBindingHandlersContainer(CommandBindingInfo binding) {
this.binding = binding;
}
/// <summary>
/// CanExecute event handler
/// </summary>
/// <param name="sender">Object which raised this event</param>
/// <param name="e">Event arguments</param>
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);
}
} }
/// <summary> public void UpdateCommandBinding() {
/// Executed event handler var newBindings = CommandsRegistry.GetCommandBindings(contextName, contextInstance, null, null);
/// </summary> CommandsRegistry.RemoveManagedCommandBindings(bindingsCollection);
/// <param name="sender">Object which raised this event</param> bindingsCollection.AddRange(newBindings);
/// <param name="e">Event arguments</param>
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);
}
} }
} }
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);
}
}
} }
} }

10
src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandsService.cs

@ -11,11 +11,11 @@ namespace ICSharpCode.Core.Presentation
/// </summary> /// </summary>
public static class CommandsService public static class CommandsService
{ {
private static void RegisterRoutedCommands(Type type) { public static void RegisterRoutedCommands(Type type) {
var typeProperties = type.GetProperties(BindingFlags.Static | BindingFlags.Public); var typeProperties = type.GetProperties(BindingFlags.Static | BindingFlags.Public);
foreach(var property in typeProperties) { foreach(var property in typeProperties) {
var command = (RoutedUICommand)property.GetValue(null, null); 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.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 gestures are provided register input binding in the same context
if(!string.IsNullOrEmpty(desc.Gestures)) { if(!string.IsNullOrEmpty(desc.Gestures)) {
var gestures = (InputGestureCollection)new InputGestureCollectionConverter().ConvertFromString(desc.Gestures); var gestures = (InputGestureCollection)new InputGestureCollectionConverter().ConvertFromString(desc.Gestures);
foreach(InputGesture gesture in 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 contextName = !string.IsNullOrEmpty(desc.Context) ? desc.Context : CommandsRegistry.DefaultContext;
var gesture = (KeyGesture)new KeyGestureConverter().ConvertFromInvariantString(desc.Gesture); var gesture = (KeyGesture)new KeyGestureConverter().ConvertFromInvariantString(desc.Gesture);
CommandsRegistry.RegisterInputBinding(contextName, desc.Command, gesture); CommandsRegistry.RegisterInputBinding(contextName, null, desc.Command, gesture);
} }
} }
} }

22
src/Main/ICSharpCode.Core.Presentation/CommandsService/InputBindingInfo.cs

@ -9,6 +9,8 @@ namespace ICSharpCode.Core.Presentation
/// </summary> /// </summary>
public class InputBindingInfo public class InputBindingInfo
{ {
private UIElement contextInstance;
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
@ -21,6 +23,14 @@ namespace ICSharpCode.Core.Presentation
Gesture = gesture; Gesture = gesture;
} }
public InputBindingInfo(string contextName, UIElement contextInstance, string routedCommandName, InputGesture gesture) {
ContextName = contextName;
RoutedCommandName = routedCommandName;
Gesture = gesture;
this.contextInstance = contextInstance;
}
/// <summary> /// <summary>
/// Context class full name /// Context class full name
/// ///
@ -37,10 +47,14 @@ namespace ICSharpCode.Core.Presentation
/// </summary> /// </summary>
public UIElement Context { public UIElement Context {
get { get {
UIElement context; if(contextInstance != null) {
CommandsRegistry.contexts.TryGetValue(ContextName, out context); return contextInstance;
} else {
return context; UIElement context;
CommandsRegistry.contexts.TryGetValue(ContextName, out context);
return context;
}
} }
} }

4
src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs

@ -127,9 +127,9 @@ namespace ICSharpCode.Core.Presentation
} else { } else {
this.Command = routedCommand; 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); var gesturesString = (string)new InputGestureCollectionConverter().ConvertToInvariantString(gestures);
this.InputGestureText = "M: " + gesturesString; this.InputGestureText = gesturesString;
} }
} else { } else {
this.Command = CommandWrapper.GetCommand(codon, caller, createCommand); this.Command = CommandWrapper.GetCommand(codon, caller, createCommand);

Loading…
Cancel
Save