Browse Source

Add support of bindings associated with whole type. Add named types and instances. Named instances and types can be used before the instance or class associated with the name is loaded

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/shortcuts@4314 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts^2
Sergej Andrejev 16 years ago
parent
commit
d7f200ab01
  1. 4
      AddIns/ICSharpCode.SharpDevelop.addin
  2. 19
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs
  3. BIN
      src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement.suo
  4. 11
      src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml.cs
  5. 18
      src/Main/Base/Project/Src/Commands/MenuItemBuilders.cs
  6. 19
      src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonPadContent.cs
  7. 20
      src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonWorkbenchWindow.cs
  8. 27
      src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs
  9. 14
      src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/CommandBindingDescriptor.cs
  10. 14
      src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/InputBindingDescriptor.cs
  11. 6
      src/Main/Core/Project/Src/AddInTree/AddIn/Runtime.cs
  12. 134
      src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandBindingInfo.cs
  13. 688
      src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandsRegistry.cs
  14. 33
      src/Main/ICSharpCode.Core.Presentation/CommandsService/CommandsService.cs
  15. 232
      src/Main/ICSharpCode.Core.Presentation/CommandsService/InputBindingInfo.cs
  16. 18
      src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs
  17. 3
      src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarButton.cs

4
AddIns/ICSharpCode.SharpDevelop.addin

@ -130,7 +130,9 @@
command="SDBuildCommands.BuildSolution" command="SDBuildCommands.BuildSolution"
class="ICSharpCode.SharpDevelop.Project.Commands.Build" class="ICSharpCode.SharpDevelop.Project.Commands.Build"
gestures="F8" gestures="F8"
category="Building" /> category="Building"
owner-instance="ICSharpCode.SharpDevelop.Gui.ClassBrowser.ClassBrowserPad"
/>
<CommandBinding <CommandBinding
command="SDBuildCommands.RebuildSolution" command="SDBuildCommands.RebuildSolution"
class="ICSharpCode.SharpDevelop.Project.Commands.Rebuild" class="ICSharpCode.SharpDevelop.Project.Commands.Rebuild"

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

@ -119,30 +119,13 @@ namespace ICSharpCode.AvalonEdit.AddIn
{ {
var contextName = this.GetType().FullName; var contextName = this.GetType().FullName;
CommandsRegistry.RegisterCommandBindingsUpdateHandler(contextName, this, delegate {
var newBindings = CommandsRegistry.FindCommandBindings(contextName, this, null, null);
CommandsRegistry.RemoveManagedCommandBindings(CommandBindings);
CommandBindings.AddRange(newBindings);
});
CommandsRegistry.RegisterInputBindingUpdateHandler(contextName, this, delegate {
var newBindings = CommandsRegistry.FindInputBindings(contextName, this, null);
CommandsRegistry.RemoveManagedInputBindings(InputBindings);
InputBindings.AddRange(newBindings);
});
var commandBindingInfo = new CommandBindingInfo(); var commandBindingInfo = new CommandBindingInfo();
commandBindingInfo.ContextName = contextName; commandBindingInfo.OwnerInstance = this;
commandBindingInfo.Context = this;
commandBindingInfo.RoutedCommandName = "SDWindowCommands.SplitView"; commandBindingInfo.RoutedCommandName = "SDWindowCommands.SplitView";
commandBindingInfo.ExecutedEventHandler = OnSplitView; commandBindingInfo.ExecutedEventHandler = OnSplitView;
commandBindingInfo.CanExecutedEventHandler = OnCanSplitView; commandBindingInfo.CanExecutedEventHandler = OnCanSplitView;
CommandsRegistry.RegisterCommandBinding(commandBindingInfo); CommandsRegistry.RegisterCommandBinding(commandBindingInfo);
CommandsRegistry.InvokeCommandBindingUpdateHandlers(contextName, this);
CommandsRegistry.InvokeInputBindingUpdateHandlers(contextName, this);
textMarkerService = new TextMarkerService(this); textMarkerService = new TextMarkerService(this);
iconBarManager = new IconBarManager(); iconBarManager = new IconBarManager();

BIN
src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement.suo

Binary file not shown.

11
src/AddIns/Misc/ShortcutsManagement/ShortcutsManagement/Src/Dialogs/ShortcutsManagementOptionsPanel.xaml.cs

@ -45,7 +45,7 @@ namespace ICSharpCode.ShortcutsManagement
rootEntries.Add(unspecifiedAddInSection); rootEntries.Add(unspecifiedAddInSection);
// Go through all input bindings // Go through all input bindings
var inputBindingInfos = CommandsRegistry.FindInputBindingInfos(null, null, null); var inputBindingInfos = CommandsRegistry.FindInputBindingInfos(null, null, null, null, null);
foreach(var inputBindingInfo in inputBindingInfos) { foreach(var inputBindingInfo in inputBindingInfos) {
// Find appropriate or create new add-in section for input binding // Find appropriate or create new add-in section for input binding
ShortcutManagement.AddIn addinSection; ShortcutManagement.AddIn addinSection;
@ -156,10 +156,17 @@ namespace ICSharpCode.ShortcutsManagement
var shortcut = pair.Key; var shortcut = pair.Key;
var inputBindingInfo = pair.Value; var inputBindingInfo = pair.Value;
if (inputBindingInfo.Gestures.Count == shortcut.Gestures.Count) {
foreach (var gesture in shortcut.Gestures) {
inputBindingInfo.Gestures.ContainsCopy(gesture);
}
} else {
inputBindingInfo.IsModifyed = true;
}
inputBindingInfo.Gestures = new InputGestureCollection(shortcut.Gestures); inputBindingInfo.Gestures = new InputGestureCollection(shortcut.Gestures);
} }
CommandsRegistry.InvokeInputBindingUpdateHandlers(null, null); CommandsRegistry.InvokeInputBindingUpdateHandlers();
return true; return true;
} }

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

@ -483,7 +483,7 @@ namespace ICSharpCode.SharpDevelop.Commands
var commandBindingInfo = new CommandBindingInfo(); var commandBindingInfo = new CommandBindingInfo();
commandBindingInfo.ClassName = routedCommandName; commandBindingInfo.ClassName = routedCommandName;
commandBindingInfo.ContextName = CommandsRegistry.DefaultContextName; commandBindingInfo.OwnerType = typeof(WpfWorkbench);
commandBindingInfo.RoutedCommandName = routedCommandName; commandBindingInfo.RoutedCommandName = routedCommandName;
commandBindingInfo.AddIn = addIn; commandBindingInfo.AddIn = addIn;
@ -491,10 +491,15 @@ namespace ICSharpCode.SharpDevelop.Commands
// If pad have shortcut specified add input binding // If pad have shortcut specified add input binding
if (!string.IsNullOrEmpty(padContent.Shortcut)) { if (!string.IsNullOrEmpty(padContent.Shortcut)) {
CommandsRegistry.RegisterClassInputBindingsUpdateHandler(CommandsRegistry.DefaultContextName, delegate {
var updatedGestures = CommandsRegistry.FindInputGestures(CommandsRegistry.DefaultContextName, null, null, null, routedCommandName);
item.InputGestureText = (string)new InputGestureCollectionConverter().ConvertToInvariantString(updatedGestures);
});
var gestures = (InputGestureCollection)new InputGestureCollectionConverter().ConvertFromString(padContent.Shortcut); var gestures = (InputGestureCollection)new InputGestureCollectionConverter().ConvertFromString(padContent.Shortcut);
var inputBindingInfo = new InputBindingInfo(); var inputBindingInfo = new InputBindingInfo();
inputBindingInfo.ContextName = CommandsRegistry.DefaultContextName; inputBindingInfo.OwnerTypeName = CommandsRegistry.DefaultContextName;
inputBindingInfo.RoutedCommandName = routedCommandName; inputBindingInfo.RoutedCommandName = routedCommandName;
inputBindingInfo.Gestures = gestures; inputBindingInfo.Gestures = gestures;
inputBindingInfo.Categories.AddRange(CommandsRegistry.RegisterInputBindingCategories("Menu Items/Views")); inputBindingInfo.Categories.AddRange(CommandsRegistry.RegisterInputBindingCategories("Menu Items/Views"));
@ -506,15 +511,6 @@ namespace ICSharpCode.SharpDevelop.Commands
bindingsAssigned.Add(routedCommandName); bindingsAssigned.Add(routedCommandName);
} }
CommandsRegistry.RegisterInputBindingUpdateHandler(CommandsRegistry.DefaultContextName, null, delegate {
var updatedGestures = CommandsRegistry.FindInputGestures(CommandsRegistry.DefaultContextName, null, routedCommandName);
item.InputGestureText = (string)new InputGestureCollectionConverter().ConvertToInvariantString(updatedGestures);
});
CommandsRegistry.InvokeCommandBindingUpdateHandlers(CommandsRegistry.DefaultContextName, null);
CommandsRegistry.InvokeInputBindingUpdateHandlers(CommandsRegistry.DefaultContextName, null);
item.Command = CommandsRegistry.GetRoutedUICommand(routedCommandName); item.Command = CommandsRegistry.GetRoutedUICommand(routedCommandName);
// item.Command = new BringPadToFrontCommand(padContent); // item.Command = new BringPadToFrontCommand(padContent);

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

@ -88,24 +88,7 @@ namespace ICSharpCode.SharpDevelop.Gui
placeholder = null; placeholder = null;
var contextName = padInstance.GetType().FullName; var contextName = padInstance.GetType().FullName;
CommandsRegistry.RegisterNamedUIElementInstance(contextName, (UIElement)Content);
CommandsRegistry.LoadContext(contextName, (UIElement)Content);
CommandsRegistry.RegisterCommandBindingsUpdateHandler(contextName, null, delegate {
var newBindings = CommandsRegistry.FindCommandBindings(contextName, null, null, null);
CommandsRegistry.RemoveManagedCommandBindings(CommandBindings);
CommandBindings.AddRange(newBindings);
});
CommandsRegistry.RegisterInputBindingUpdateHandler(contextName, null, delegate {
var newBindings = CommandsRegistry.FindInputBindings(contextName, null, null);
CommandsRegistry.RemoveManagedInputBindings(InputBindings);
InputBindings.AddRange(newBindings);
});
CommandsRegistry.InvokeCommandBindingUpdateHandlers(contextName, null);
CommandsRegistry.InvokeInputBindingUpdateHandlers(contextName, null);
} }
} }
} }

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

@ -93,24 +93,8 @@ namespace ICSharpCode.SharpDevelop.Gui
CommandManager.InvalidateRequerySuggested(); CommandManager.InvalidateRequerySuggested();
if (newActiveViewContent != null) { if (newActiveViewContent != null) {
string contextName = newActiveViewContent.GetType().FullName; string ownerName = newActiveViewContent.GetType().FullName;
CommandsRegistry.RegisterNamedUIElementInstance(ownerName, (UIElement)Content);
CommandsRegistry.LoadContext(contextName, (UIElement)Content);
CommandsRegistry.RegisterCommandBindingsUpdateHandler(contextName, null, delegate {
var newBindings = CommandsRegistry.FindCommandBindings(contextName, null, null, null);
CommandsRegistry.RemoveManagedCommandBindings(CommandBindings);
CommandBindings.AddRange(newBindings);
});
CommandsRegistry.RegisterInputBindingUpdateHandler(contextName, null, delegate {
var newBindings = CommandsRegistry.FindInputBindings(contextName, null, null);
CommandsRegistry.RemoveManagedInputBindings(InputBindings);
InputBindings.AddRange(newBindings);
});
CommandsRegistry.InvokeCommandBindingUpdateHandlers(contextName, null);
CommandsRegistry.InvokeInputBindingUpdateHandlers(contextName, null);
} }
} }

27
src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs

@ -80,7 +80,7 @@ namespace ICSharpCode.SharpDevelop.Gui
} }
} }
CommandsRegistry.DefaultContextName = this.GetType().Name; CommandsRegistry.DefaultContextName = this.GetType().AssemblyQualifiedName;
CommandsService.RegisterBuiltInRoutedUICommands(); CommandsService.RegisterBuiltInRoutedUICommands();
@ -92,20 +92,17 @@ 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.DefaultContextName, null, delegate { //CommandsRegistry.RegisterCommandBindingsUpdateHandler(CommandsRegistry.DefaultContextName, null, delegate {
var newBindings = CommandsRegistry.FindCommandBindings(CommandsRegistry.DefaultContextName, null, null, null); // var newBindings = CommandsRegistry.FindCommandBindings(CommandsRegistry.DefaultContextName, null, null, null);
CommandsRegistry.RemoveManagedCommandBindings(CommandBindings); // CommandsRegistry.RemoveManagedCommandBindings(CommandBindings);
CommandBindings.AddRange(newBindings); // CommandBindings.AddRange(newBindings);
}); //});
CommandsRegistry.RegisterInputBindingUpdateHandler(CommandsRegistry.DefaultContextName, null, delegate { //CommandsRegistry.RegisterInputBindingUpdateHandler(CommandsRegistry.DefaultContextName, null, delegate {
var newBindings = CommandsRegistry.FindInputBindings(null, null, null); // var newBindings = CommandsRegistry.FindInputBindings(null, null, null);
CommandsRegistry.RemoveManagedInputBindings(InputBindings); // CommandsRegistry.RemoveManagedInputBindings(InputBindings);
InputBindings.AddRange(newBindings); // InputBindings.AddRange(newBindings);
}); //});
CommandsRegistry.InvokeCommandBindingUpdateHandlers(CommandsRegistry.DefaultContextName, null);
CommandsRegistry.InvokeInputBindingUpdateHandlers(CommandsRegistry.DefaultContextName, null);
mainMenu.ItemsSource = MenuService.CreateMenuItems(this, this, mainMenuPath); mainMenu.ItemsSource = MenuService.CreateMenuItems(this, this, mainMenuPath);

14
src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/CommandBindingDescriptor.cs

@ -38,12 +38,11 @@ namespace ICSharpCode.Core
get; private set; get; private set;
} }
/// <summary> public string OwnerInstanceName {
/// Full name of context class. get; private set;
/// }
/// UI element in which this binding will be valid
/// </summary> public string OwnerTypeName {
public string Context {
get; private set; get; private set;
} }
@ -86,7 +85,8 @@ namespace ICSharpCode.Core
Class = Codon.Properties["class"]; Class = Codon.Properties["class"];
Command = Codon.Properties["command"]; Command = Codon.Properties["command"];
CommandText = Codon.Properties["commandtext"]; CommandText = Codon.Properties["commandtext"];
Context = Codon.Properties["context"]; OwnerInstanceName = Codon.Properties["owner-instance"];
OwnerTypeName = Codon.Properties["owner-type"];
Gestures = Codon.Properties["gestures"]; Gestures = Codon.Properties["gestures"];
Category = Codon.Properties["category"]; Category = Codon.Properties["category"];
} }

14
src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Command/InputBindingDescriptor.cs

@ -28,12 +28,11 @@ namespace ICSharpCode.Core
get; private set; get; private set;
} }
/// <summary> public string OwnerInstanceName {
/// Full name of context class. get; private set;
/// }
/// UI element in which this binding will be valid
/// </summary> public string OwnerTypeName {
public string Context {
get; private set; get; private set;
} }
@ -60,7 +59,8 @@ namespace ICSharpCode.Core
Codon = codon; Codon = codon;
Command = codon.Properties["command"]; Command = codon.Properties["command"];
CommandText = codon.Properties["commandtext"]; CommandText = codon.Properties["commandtext"];
Context = codon.Properties["context"]; OwnerInstanceName = codon.Properties["owner-instance"];
OwnerTypeName = codon.Properties["owner-type"];
Gestures = codon.Properties["gestures"]; Gestures = codon.Properties["gestures"];
Category = codon.Properties["category"]; Category = codon.Properties["category"];
} }

6
src/Main/Core/Project/Src/AddInTree/AddIn/Runtime.cs

@ -84,6 +84,10 @@ namespace ICSharpCode.Core
// preload assembly to provoke FileLoadException if dependencies are missing // preload assembly to provoke FileLoadException if dependencies are missing
loadedAssembly.GetExportedTypes(); loadedAssembly.GetExportedTypes();
#endif #endif
if(Loaded != null) {
Loaded(this, null);
}
} catch (FileNotFoundException ex) { } catch (FileNotFoundException ex) {
MessageService.ShowError("The addin '" + assembly + "' could not be loaded:\n" + ex.ToString()); MessageService.ShowError("The addin '" + assembly + "' could not be loaded:\n" + ex.ToString());
} catch (FileLoadException ex) { } catch (FileLoadException ex) {
@ -92,6 +96,8 @@ namespace ICSharpCode.Core
} }
} }
public event EventHandler Loaded;
public Assembly LoadedAssembly { public Assembly LoadedAssembly {
get { get {
Load(); // load the assembly, if not already done Load(); // load the assembly, if not already done

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

@ -9,11 +9,11 @@ namespace ICSharpCode.Core.Presentation
/// </summary> /// </summary>
public class CommandBindingInfo public class CommandBindingInfo
{ {
private UIElement contextInstance;
public CommandBindingInfo() public CommandBindingInfo()
{ {
ContextName = CommandsRegistry.DefaultContextName; IsModifyed = true;
OldCommandBindings = new CommandBindingCollection();
NewCommandBindings = new CommandBindingCollection();
} }
/// <summary> /// <summary>
@ -90,28 +90,105 @@ namespace ICSharpCode.Core.Presentation
} }
/// <summary> /// <summary>
/// Name of the class which owns this binding /// Store name of object owning this binding (can only be used with named objects)
///
/// Named objects can be registered throgut <see cref="CommandsRegistry.RegisterNamedUIElementInstance" />
/// </summary> /// </summary>
public string ContextName{ public string OwnerInstanceName{
get; set; get; set;
} }
private UIElement ownerInstance;
/// <summary> /// <summary>
/// Instance of class which owns this binding /// Stores instance of object which is owning this binding
/// </summary> /// </summary>
public UIElement Context { public UIElement OwnerInstance{
get {
if(OwnerInstanceName != null && ownerInstance == null) {
ownerInstance = CommandsRegistry.GetNamedUIElementInstance(OwnerInstanceName);
}
return ownerInstance;
}
set { set {
contextInstance = value; ownerInstance = value;
}
}
/// <summary>
/// Assembly qualified name of the class owning this instance
///
/// Named type can be registered throgut <see cref="CommandsRegistry.RegisterNamedUIType" />
/// </summary>
public string OwnerTypeName{
get; set;
}
private Type ownerType;
/// <summary>
/// Stores type owning this binding
/// </summary>
public Type OwnerType {
set {
ownerType = value;
} }
get { get {
if(contextInstance != null) { if(ownerType == null && OwnerTypeName != null) {
return contextInstance; ownerType = Type.GetType(OwnerTypeName);
} else { CommandsRegistry.RegisterNamedUIType(OwnerTypeName, ownerType);
UIElement context; }
CommandsRegistry.contexts.TryGetValue(ContextName, out context);
return context; return ownerType;
}
}
/// <summary>
/// Default binding update handler update owner or type bindings (depending on input binding info type)
/// so they would always contain latest version
/// </summary>
private BindingsUpdatedHandler defaultCommandBindingHandler;
/// <summary>
/// Default command binding handler. Updates command binding if binding info changes
/// </summary>
internal BindingsUpdatedHandler DefaultCommandBindingHandler
{
get {
if(defaultCommandBindingHandler == null && (OwnerTypeName != null || OwnerType != null)) {
defaultCommandBindingHandler = delegate {
if(OwnerType != null && IsModifyed) {
GenerateCommandBindings();
foreach(ManagedCommandBinding binding in OldCommandBindings) {
CommandsRegistry.RemoveClassCommandBinding(OwnerType, binding);
}
foreach(ManagedCommandBinding binding in NewCommandBindings) {
CommandManager.RegisterClassCommandBinding(OwnerType, binding);
}
IsModifyed = false;
}
};
} else if(defaultCommandBindingHandler == null && (OwnerInstanceName != null || OwnerInstance != null)) {
defaultCommandBindingHandler = delegate {
if(OwnerInstance != null && IsModifyed) {
GenerateCommandBindings();
foreach(ManagedCommandBinding binding in OldCommandBindings) {
OwnerInstance.CommandBindings.Remove(binding);
}
OwnerInstance.CommandBindings.AddRange(NewCommandBindings);
IsModifyed = false;
}
};
} }
return defaultCommandBindingHandler;
} }
} }
@ -137,6 +214,35 @@ namespace ICSharpCode.Core.Presentation
get; set; get; set;
} }
/// <summary>
/// Indicates that generated command bindings are modified from last access
/// </summary>
public bool IsModifyed {
get; set;
}
public void GenerateCommandBindings()
{
OldCommandBindings = NewCommandBindings;
var managedCommandBinding = new ManagedCommandBinding(RoutedCommand);
managedCommandBinding.CanExecute += GeneratedCanExecuteEventHandler;
managedCommandBinding.Executed += GeneratedExecutedEventHandler;
NewCommandBindings = new CommandBindingCollection();
NewCommandBindings.Add(managedCommandBinding);
}
internal CommandBindingCollection OldCommandBindings
{
get; set;
}
internal CommandBindingCollection NewCommandBindings
{
get; set;
}
internal void GeneratedExecutedEventHandler(object sender, ExecutedRoutedEventArgs e) { internal void GeneratedExecutedEventHandler(object sender, ExecutedRoutedEventArgs e) {
if(ExecutedEventHandler != null) { if(ExecutedEventHandler != null) {
ExecutedEventHandler.Invoke(sender, e); ExecutedEventHandler.Invoke(sender, e);

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

@ -7,6 +7,8 @@ using System.Threading;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Collections.Specialized;
namespace ICSharpCode.Core.Presentation namespace ICSharpCode.Core.Presentation
{ {
@ -31,18 +33,111 @@ namespace ICSharpCode.Core.Presentation
get; set; get; set;
} }
// Binding infos
private static List<CommandBindingInfo> commandBindings = new List<CommandBindingInfo>(); private static List<CommandBindingInfo> commandBindings = new List<CommandBindingInfo>();
private static List<InputBindingInfo> inputBidnings = new List<InputBindingInfo>(); private static List<InputBindingInfo> inputBidnings = new List<InputBindingInfo>();
// Commands
private static Dictionary<string, RoutedUICommand> routedCommands = new Dictionary<string, RoutedUICommand>(); private static Dictionary<string, RoutedUICommand> routedCommands = new Dictionary<string, RoutedUICommand>();
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>();
private static Dictionary<string, Dictionary<UIElement, List<BindingsUpdatedHandler>>> commandBindingsUpdateHandlers = new Dictionary<string, Dictionary<UIElement, List<BindingsUpdatedHandler>>>(); // Update hanlers
private static Dictionary<string, Dictionary<UIElement, List<BindingsUpdatedHandler>>> inputBindingsUpdateHandlers = new Dictionary<string, Dictionary<UIElement, List<BindingsUpdatedHandler>>>(); private static Dictionary<string, List<BindingsUpdatedHandler>> classCommandBindingUpdateHandlers = new Dictionary<string, List<BindingsUpdatedHandler>>();
private static Dictionary<object, List<BindingsUpdatedHandler>> instanceCommandBindingUpdateHandlers = new Dictionary<object, List<BindingsUpdatedHandler>>();
private static Dictionary<string, List<BindingsUpdatedHandler>> classInputBindingUpdateHandlers = new Dictionary<string, List<BindingsUpdatedHandler>>();
private static Dictionary<object, List<BindingsUpdatedHandler>> instanceInputBindingUpdateHandlers = new Dictionary<object, List<BindingsUpdatedHandler>>();
// Named instances and types
private static Dictionary<string, UIElement> namedUIInstances = new Dictionary<string, UIElement>();
private static Dictionary<string, Type> namedUITypes = new Dictionary<string, Type>();
// Categories
private static List<InputBindingCategory> categories = new List<InputBindingCategory>(); private static List<InputBindingCategory> categories = new List<InputBindingCategory>();
/// <summary>
/// Register UI element instance accessible by unique name
/// </summary>
/// <param name="instanceName">Instance name</param>
/// <param name="element">Instance</param>
public static void RegisterNamedUIElementInstance(string instanceName, UIElement element)
{
if(!namedUIInstances.ContainsKey(instanceName)){
namedUIInstances.Add(instanceName, element);
// If there are some bindings and update handlers already registered,
// but owner is not loaded then move these to arrays which holds bindings
// and update handlers of loaded instances
if(instanceCommandBindingUpdateHandlers.ContainsKey(instanceName)) {
foreach(var handler in instanceCommandBindingUpdateHandlers[instanceName]) {
RegisterInstanceCommandBindingsUpdateHandler(element, handler);
}
instanceCommandBindingUpdateHandlers.Remove(instanceName);
InvokeInstanceCommandBindingUpdateHandlers(element);
foreach(var handler in instanceInputBindingUpdateHandlers[instanceName]) {
RegisterInstanceInputBindingsUpdateHandler(element, handler);
}
instanceInputBindingUpdateHandlers.Remove(instanceName);
InvokeInstanceInputBindingUpdateHandlers(element);
}
}
}
/// <summary>
/// Get instance by unique instance name
/// </summary>
/// <param name="instanceName">Instance name</param>
/// <returns></returns>
public static UIElement GetNamedUIElementInstance(string instanceName)
{
UIElement instance;
namedUIInstances.TryGetValue(instanceName, out instance);
return instance;
}
/// <summary>
/// Register UI type which can be accessible by name
/// </summary>
/// <param name="typeName">Type name</param>
/// <param name="type">Type</param>
public static void RegisterNamedUIType(string typeName, Type type)
{
if(!namedUITypes.ContainsKey(typeName)){
namedUITypes.Add(typeName, type);
// If any bindings or update handlers where assigned to the type
// before it was loaded using unique name move these to array
// holding type bindings and update handlers
if(classCommandBindingUpdateHandlers.ContainsKey(typeName)) {
foreach(var handler in classCommandBindingUpdateHandlers[typeName]) {
RegisterClassCommandBindingsUpdateHandler(type, handler);
}
classCommandBindingUpdateHandlers.Remove(typeName);
InvokeClassCommandBindingUpdateHandlers(type);
foreach(var handler in classInputBindingUpdateHandlers[typeName]) {
RegisterClassInputBindingsUpdateHandler(type, handler);
}
classInputBindingUpdateHandlers.Remove(typeName);
InvokeClassInputBindingUpdateHandlers(type);
}
}
}
/// <summary>
/// Get type by uniqe type name
/// </summary>
/// <param name="typeName">Type name</param>
/// <returns>Type</returns>
public static Type GetNamedUIType(string typeName)
{
Type instance;
namedUITypes.TryGetValue(typeName, out instance);
return instance;
}
/// <summary> /// <summary>
/// Get reference to routed UI command by name /// Get reference to routed UI command by name
/// </summary> /// </summary>
@ -121,7 +216,14 @@ namespace ICSharpCode.Core.Presentation
public static void RegisterInputBinding(InputBindingInfo inputBindingInfo) public static void RegisterInputBinding(InputBindingInfo inputBindingInfo)
{ {
inputBidnings.Add(inputBindingInfo); inputBidnings.Add(inputBindingInfo);
CommandsRegistry.InvokeCommandBindingUpdateHandlers(inputBindingInfo.ContextName, null);
if(inputBindingInfo.OwnerTypeName != null || inputBindingInfo.OwnerType != null) {
RegisterClassDefaultInputBindingHandler(inputBindingInfo);
} else if (inputBindingInfo.OwnerInstanceName != null || inputBindingInfo.OwnerInstance != null) {
RegisterInstaceDefaultInputBindingHandler(inputBindingInfo);
} else {
throw new ArgumentException("Binding owner must be specified");
}
} }
/// <summary> /// <summary>
@ -134,20 +236,24 @@ namespace ICSharpCode.Core.Presentation
} }
/// <summary> /// <summary>
/// Find input input bindings which satisfy provided arguments /// Find input input binding infos which satisfy provided arguments
/// ///
/// 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="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>
public static ICollection<InputBindingInfo> FindInputBindingInfos(string contextName, UIElement contextInstance, string routedCommandName) { public static ICollection<InputBindingInfo> FindInputBindingInfos(string ownerTypeName, Type ownerType, string ownerInstanceName, UIElement ownerInstance, string routedCommandName) {
var foundBindings = new List<InputBindingInfo>(); var foundBindings = new List<InputBindingInfo>();
for(int i = inputBidnings.Count - 1; i >= 0; i--) {
if((contextName == null || inputBidnings[i].ContextName == contextName) foreach(var binding in inputBidnings) {
&& (contextInstance == null || inputBidnings[i].Context == null || inputBidnings[i].Context == contextInstance) if( (ownerInstanceName == null || binding.OwnerInstanceName == ownerInstanceName)
&& (routedCommandName == null || inputBidnings[i].RoutedCommandName == routedCommandName)) { && (ownerInstance == null || binding.OwnerInstance == ownerInstance)
foundBindings.Add(inputBidnings[i]); && (ownerTypeName == null || binding.OwnerTypeName == ownerTypeName)
&& (ownerType == null || binding.OwnerType == ownerType)
&& (routedCommandName == null || binding.RoutedCommandName == routedCommandName)) {
foundBindings.Add(binding);
} }
} }
@ -155,211 +261,345 @@ namespace ICSharpCode.Core.Presentation
} }
/// <summary> /// <summary>
/// Register delegate which will be invoked on change in input bindings in specified context /// Remove input binding associated with type
/// </summary> /// </summary>
/// <param name="contextName">Context class full name</param> /// <param name="ownerType">Owner type</param>
/// <param name="contextInstance">Register update handler which will trigger only if input bindings registered for this object where triggered</param> /// <param name="inputBinding">Input binding</param>
/// <param name="handler">Update handler delegate</param> public static void RemoveClassInputBinding(Type ownerType, InputBinding inputBinding)
public static void RegisterInputBindingUpdateHandler(string contextName, UIElement contextInstance, BindingsUpdatedHandler handler) { {
if(contextInstance == null) { var fieldInfo = typeof(CommandManager).GetField("_classInputBindings", BindingFlags.Static | BindingFlags.NonPublic);
contextInstance = NullUIElement; var fieldData = (HybridDictionary)fieldInfo.GetValue(null);
} var classInputBindings = (InputBindingCollection)fieldData[ownerType];
if(!inputBindingsUpdateHandlers.ContainsKey(contextName)) { if(classInputBindings != null) {
inputBindingsUpdateHandlers.Add(contextName, new Dictionary<UIElement, List<BindingsUpdatedHandler>>()); classInputBindings.Remove(inputBinding);
} }
}
if(!inputBindingsUpdateHandlers[contextName].ContainsKey(contextInstance)) { /// <summary>
inputBindingsUpdateHandlers[contextName].Add(contextInstance, new List<BindingsUpdatedHandler>()); /// Remove command binding associated with type
/// </summary>
/// <param name="ownerType"></param>
/// <param name="commandBinding"></param>
public static void RemoveClassCommandBinding(Type ownerType, CommandBinding commandBinding)
{
var fieldInfo = typeof(CommandManager).GetField("_classCommandBindings", BindingFlags.Static | BindingFlags.NonPublic);
var fieldData = (HybridDictionary)fieldInfo.GetValue(null);
var classCommandBindings = (CommandBindingCollection)fieldData[ownerType];
if(classCommandBindings != null) {
classCommandBindings.Remove(commandBinding);
} }
}
/// <summary>
/// Register command binding by specifying command binding parameters
/// </summary>
/// <param name="commandBindingInfo">Command binding parameters</param>
public static void RegisterCommandBinding(CommandBindingInfo commandBindingInfo) {
commandBindings.Add(commandBindingInfo);
commandBindingInfo.GenerateCommandBindings();
inputBindingsUpdateHandlers[contextName][contextInstance].Add(handler); if(commandBindingInfo.OwnerTypeName != null || commandBindingInfo.OwnerType != null) {
RegisterClassDefaultCommandBindingHandler(commandBindingInfo);
} else if (commandBindingInfo.OwnerInstanceName != null || commandBindingInfo.OwnerInstance != null) {
RegisterInstaceDefaultCommandBindingHandler(commandBindingInfo);
} else {
throw new ArgumentException("Binding owner must be specified");
}
} }
/// <summary> /// <summary>
/// Remove input bindings update handler /// Unregister command binding
/// </summary> /// </summary>
/// <param name="contextName">Context class full name</param> /// <param name="commandBindingInfo">Command binding parameters</param>
/// <param name="contextInstance">Unregister update handler which was triggered only if input bindings registered for specific instance where updated</param> public static void UnregisterCommandBinding(CommandBindingInfo commandBindingInfo) {
/// <param name="handler">Update handler delegate</param> commandBindings.Remove(commandBindingInfo);
public static void UnregisterInputBindingUpdateHandler(string contextName, UIElement contextInstance, BindingsUpdatedHandler handler) {
if(contextInstance == null) { // Remove command bindings
contextInstance = NullUIElement; if(commandBindingInfo.OwnerType != null) {
} foreach(ManagedCommandBinding binding in commandBindingInfo.OldCommandBindings) {
if(!inputBindingsUpdateHandlers.ContainsKey(contextName)) { RemoveClassCommandBinding(commandBindingInfo.OwnerType, binding);
if(!inputBindingsUpdateHandlers[contextName].ContainsKey(contextInstance)) { }
for(int i = inputBindingsUpdateHandlers[contextName][contextInstance].Count - 1; i >= 0; i++) {
if(inputBindingsUpdateHandlers[contextName][contextInstance][i] == handler) { foreach(ManagedCommandBinding binding in commandBindingInfo.NewCommandBindings) {
inputBindingsUpdateHandlers[contextName][contextInstance].RemoveAt(i); RemoveClassCommandBinding(commandBindingInfo.OwnerType, binding);
} }
} } else if (commandBindingInfo.OwnerInstance != null) {
foreach(ManagedCommandBinding binding in commandBindingInfo.OldCommandBindings) {
commandBindingInfo.OwnerInstance.CommandBindings.Remove(binding);
}
foreach(ManagedCommandBinding binding in commandBindingInfo.NewCommandBindings) {
commandBindingInfo.OwnerInstance.CommandBindings.Remove(binding);
} }
} }
} }
#region Register bindings update handler
/// <summary> /// <summary>
/// Invoke registered input bindings update handlers registered in specified context /// Register command binding update handler which is triggered when input bindings associated
/// with specified type change
/// </summary> /// </summary>
/// <param name="contextName">Context class full name</param> /// <param name="ownerType">Owner type</param>
public static void InvokeInputBindingUpdateHandlers(string contextName, UIElement contextInstance) { /// <param name="handler">Update handler</param>
if(contextInstance == null) { public static void RegisterClassCommandBindingsUpdateHandler(Type ownerType, BindingsUpdatedHandler handler)
contextInstance = NullUIElement; {
} RegisterClassCommandBindingsUpdateHandler(ownerType.AssemblyQualifiedName, handler);
}
if(contextName != null) {
if(inputBindingsUpdateHandlers.ContainsKey(contextName)) { /// <summary>
if(contextInstance == NullUIElement) { /// Register command binding update handler which is triggered when input bindings associated
foreach(var instanceHandlers in inputBindingsUpdateHandlers[contextName]) { /// with specified type change
foreach(var handler in instanceHandlers.Value) { /// </summary>
if(handler != null) { /// <param name="ownerTypeName">Owner type name</param>
((BindingsUpdatedHandler)handler).Invoke(); /// <param name="handler">Update handler</param>
} public static void RegisterClassCommandBindingsUpdateHandler(string ownerTypeName, BindingsUpdatedHandler handler)
} {
} if(!classCommandBindingUpdateHandlers.ContainsKey(ownerTypeName)) {
} classCommandBindingUpdateHandlers.Add(ownerTypeName, new List<BindingsUpdatedHandler>());
} else if(inputBindingsUpdateHandlers[contextName].ContainsKey(contextInstance)) { }
foreach(var handler in inputBindingsUpdateHandlers[contextName][contextInstance]) {
if(handler != null) { if(!classCommandBindingUpdateHandlers[ownerTypeName].Contains(handler)) {
((BindingsUpdatedHandler)handler).Invoke(); classCommandBindingUpdateHandlers[ownerTypeName].Add(handler);
} }
} }
}
/// <summary>
/// Register command binding update handler which is triggered when input bindings associated
/// with specified instance change
/// </summary>
/// <param name="instanceName">Owner instance name</param>
/// <param name="handler">Update handler</param>
public static void RegisterInstanceCommandBindingsUpdateHandler(string instanceName, BindingsUpdatedHandler handler)
{
var instance = GetNamedUIElementInstance(instanceName);
if(instance != null) {
RegisterInstanceCommandBindingsUpdateHandler(instance, handler);
} else { } else {
foreach(var contextHandlers in inputBindingsUpdateHandlers) { if(!instanceCommandBindingUpdateHandlers.ContainsKey(instanceName)) {
foreach(var instanceHandlers in contextHandlers.Value) { instanceCommandBindingUpdateHandlers.Add(instanceName, new List<BindingsUpdatedHandler>());
foreach(var handler in instanceHandlers.Value) {
if(handler != null) {
((BindingsUpdatedHandler)handler).Invoke();
}
}
}
} }
instanceCommandBindingUpdateHandlers[instanceName].Add(handler);
} }
} }
/// <summary> /// <summary>
/// Remove all managed input bindings from <see cref="InputBindingCollection" /> /// Register command binding update handler which is triggered when input bindings associated
/// with specified instance change
/// </summary> /// </summary>
/// <param name="inputBindingCollection">Input binding cllection containing managed input bindings</param> /// <param name="instance">Owner instance</param>
public static void RemoveManagedInputBindings(InputBindingCollection inputBindingCollection) { /// <param name="handler">Update handler</param>
for(int i = inputBindingCollection.Count - 1; i >= 0; i--) { public static void RegisterInstanceCommandBindingsUpdateHandler(UIElement instance, BindingsUpdatedHandler handler)
if(inputBindingCollection[i] is ManagedInputBinding) { {
inputBindingCollection.RemoveAt(i); if(!instanceCommandBindingUpdateHandlers.ContainsKey(instance)) {
instanceCommandBindingUpdateHandlers.Add(instance, new List<BindingsUpdatedHandler>());
}
instanceCommandBindingUpdateHandlers[instance].Add(handler);
}
/// <summary>
/// Register input binding update handler which is triggered when input bindings associated
/// with specified type change
/// </summary>
/// <param name="ownerType">Owner type</param>
/// <param name="handler">Update handler</param>
public static void RegisterClassInputBindingsUpdateHandler(Type ownerType, BindingsUpdatedHandler handler)
{
RegisterClassInputBindingsUpdateHandler(ownerType.AssemblyQualifiedName, handler);
}
/// <summary>
/// Register input binding update handler which is triggered when input bindings associated
/// with specified type change
/// </summary>
/// <param name="ownerTypeName">Owner type name</param>
/// <param name="handler">Update handler</param>
public static void RegisterClassInputBindingsUpdateHandler(string ownerTypeName, BindingsUpdatedHandler handler)
{
if(!classInputBindingUpdateHandlers.ContainsKey(ownerTypeName)) {
classInputBindingUpdateHandlers.Add(ownerTypeName, new List<BindingsUpdatedHandler>());
}
if(!classInputBindingUpdateHandlers[ownerTypeName].Contains(handler)) {
classInputBindingUpdateHandlers[ownerTypeName].Add(handler);
}
}
/// <summary>
/// Register input binding update handler which is triggered when input bindings associated
/// with specified instance change
/// </summary>
/// <param name="instanceName">Owner instance name</param>
/// <param name="handler">Update handler</param>
public static void RegisterInstanceInputBindingsUpdateHandler(string instanceName, BindingsUpdatedHandler handler)
{
var instance = GetNamedUIElementInstance(instanceName);
if(instance != null) {
RegisterInstanceInputBindingsUpdateHandler(instance, handler);
} else {
if(!instanceInputBindingUpdateHandlers.ContainsKey(instanceName)) {
instanceInputBindingUpdateHandlers.Add(instanceName, new List<BindingsUpdatedHandler>());
} }
instanceInputBindingUpdateHandlers[instanceName].Add(handler);
} }
} }
/// <summary> /// <summary>
/// Register command binding by specifying command binding parameters /// Register input binding update handler which is triggered when input bindings associated
/// with specified instance change
/// </summary> /// </summary>
/// <param name="commandBindingInfo">Command binding parameters</param> /// <param name="instance">Owner instance</param>
public static void RegisterCommandBinding(CommandBindingInfo commandBindingInfo) { /// <param name="handler">Update handler</param>
commandBindings.Add(commandBindingInfo); public static void RegisterInstanceInputBindingsUpdateHandler(UIElement instance, BindingsUpdatedHandler handler)
{
if(!instanceInputBindingUpdateHandlers.ContainsKey(instance)) {
instanceInputBindingUpdateHandlers.Add(instance, new List<BindingsUpdatedHandler>());
}
instanceInputBindingUpdateHandlers[instance].Add(handler);
} }
#endregion
#region Invoke binding update handlers
/// <summary> /// <summary>
/// Unregister command binding /// Invoke all inbut binding update handlers
/// </summary> /// </summary>
/// <param name="commandBindingInfo">Command binding parameters</param> public static void InvokeInputBindingUpdateHandlers()
public static void UnregisterCommandBinding(CommandBindingInfo commandBindingInfo) { {
commandBindings.Remove(commandBindingInfo); foreach(var instanceHandlers in instanceInputBindingUpdateHandlers) {
foreach(var handler in instanceHandlers.Value) {
handler.Invoke();
}
}
foreach(var classHandlers in classInputBindingUpdateHandlers) {
foreach(var handler in classHandlers.Value) {
handler.Invoke();
}
}
} }
/// <summary> /// <summary>
/// Register delegate which will be invoked on any chage in command bindings of specified context /// Invoke all command binding update handlers
/// </summary> /// </summary>
/// <param name="contextName">Context class full name</param> public static void InvokeCommandBindingUpdateHandlers()
/// <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> foreach(var instanceHandlers in instanceCommandBindingUpdateHandlers) {
public static void RegisterCommandBindingsUpdateHandler(string contextName, UIElement contextInstance, BindingsUpdatedHandler handler) { foreach(var handler in instanceHandlers.Value) {
if(contextInstance == null) { handler.Invoke();
contextInstance = NullUIElement; }
} }
if(!commandBindingsUpdateHandlers.ContainsKey(contextName)) {
commandBindingsUpdateHandlers.Add(contextName, new Dictionary<UIElement, List<BindingsUpdatedHandler>>()); foreach(var classHandlers in classCommandBindingUpdateHandlers) {
foreach(var handler in classHandlers.Value) {
handler.Invoke();
}
} }
}
if(!commandBindingsUpdateHandlers[contextName].ContainsKey(contextInstance)) { /// <summary>
commandBindingsUpdateHandlers[contextName].Add(contextInstance, new List<BindingsUpdatedHandler>()); /// Invoke command binding update handlers associated with UI element instance
/// </summary>
/// <param name="owner">Owner instance</param>
public static void InvokeInstanceCommandBindingUpdateHandlers(UIElement owner)
{
if(instanceCommandBindingUpdateHandlers.ContainsKey(owner)) {
foreach(var handler in instanceCommandBindingUpdateHandlers[owner]) {
handler.Invoke();
}
} }
}
commandBindingsUpdateHandlers[contextName][contextInstance].Add(handler); /// <summary>
/// Invoke command binding update handlers associated with UI element instance
/// </summary>
/// <param name="owner">Owner instance name</param>
public static void InvokeInstanceCommandBindingUpdateHandlers(string ownerName)
{
if(instanceCommandBindingUpdateHandlers.ContainsKey(ownerName)) {
foreach(var handler in instanceCommandBindingUpdateHandlers[ownerName]) {
handler.Invoke();
}
}
} }
/// <summary> /// <summary>
/// Remove handler command bindings update handler /// Invoke command binding update handlers associated with UI element type
/// </summary> /// </summary>
/// <param name="contextName">Context class full name</param> /// <param name="owner">Owner type</param>
/// <param name="contextInstance">Unregister update handler which was triggered only if input bindings registered for specific instance were updated</param> public static void InvokeClassCommandBindingUpdateHandlers(Type ownerType)
/// <param name="handler">Update handler delegate</param> {
public static void UnregisterCommandBindingsUpdateHandler(string contextName, UIElement contextInstance, BindingsUpdatedHandler handler) { InvokeClassCommandBindingUpdateHandlers(ownerType.AssemblyQualifiedName);
if(contextInstance == null) { }
contextInstance = NullUIElement;
} /// <summary>
if(commandBindingsUpdateHandlers.ContainsKey(contextName)) { /// Invoke command binding update handlers associated with UI element type
if(commandBindingsUpdateHandlers[contextName].ContainsKey(contextInstance)) { /// </summary>
for(int i = commandBindingsUpdateHandlers[contextName][contextInstance].Count - 1; i >= 0; i--) { /// <param name="owner">Owner type name</param>
if(commandBindingsUpdateHandlers[contextName][contextInstance][i] == handler) { public static void InvokeClassCommandBindingUpdateHandlers(string ownerTypeName)
commandBindingsUpdateHandlers[contextName][contextInstance].RemoveAt(i); {
} if(instanceCommandBindingUpdateHandlers.ContainsKey(ownerTypeName)) {
} foreach(var handler in classCommandBindingUpdateHandlers[ownerTypeName]) {
handler.Invoke();
} }
} }
} }
/// <summary> /// <summary>
/// Invoke registered command bindings update handlers registered in specified context /// Invoke input binding update handlers associated with UI element instance
/// </summary> /// </summary>
/// <param name="contextName">Context class full name</param> /// <param name="owner">Owner instance</param>
/// <param name="contextInstance">Invoke update handlers which handle update only in specifyc context</param> public static void InvokeInstanceInputBindingUpdateHandlers(UIElement owner)
public static void InvokeCommandBindingUpdateHandlers(string contextName, UIElement contextInstance) { {
if(contextInstance == null) { if(instanceInputBindingUpdateHandlers.ContainsKey(owner)) {
contextInstance = NullUIElement; foreach(var handler in instanceInputBindingUpdateHandlers[owner]) {
} handler.Invoke();
if(contextName != null) {
if(commandBindingsUpdateHandlers.ContainsKey(contextName)) {
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 instanceHandlers in contextHandlers.Value) {
foreach(var handler in instanceHandlers.Value) { /// <summary>
if(handler != null) { /// Invoke input binding update handlers associated with UI element instance
((BindingsUpdatedHandler)handler).Invoke(); /// </summary>
} /// <param name="ownerName">Owner instance name</param>
} public static void InvokeInstanceInputBindingUpdateHandlers(string ownerName)
} {
if(instanceInputBindingUpdateHandlers.ContainsKey(ownerName)) {
foreach(var handler in instanceInputBindingUpdateHandlers[ownerName]) {
handler.Invoke();
} }
} }
} }
/// <summary> /// <summary>
/// Remove all managed command bindings from <see cref="CommandBindingCollection" /> /// Invoke input binding update handlers associated with UI element type
/// </summary>
/// <param name="owner">Owner type</param>
public static void InvokeClassInputBindingUpdateHandlers(Type ownerType)
{
InvokeClassInputBindingUpdateHandlers(ownerType.AssemblyQualifiedName);
}
/// <summary>
/// Invoke input binding update handlers associated with UI element type
/// </summary> /// </summary>
/// <param name="commandBindingsCollection">Command binding cllection containing managed input bindings</param> /// <param name="owner">Owner type name</param>
public static void RemoveManagedCommandBindings(CommandBindingCollection commandBindingsCollection) { public static void InvokeClassInputBindingUpdateHandlers(string ownerTypeName)
for(int i = commandBindingsCollection.Count - 1; i >= 0; i--) { {
if(commandBindingsCollection[i] is ManagedCommandBinding) { if(instanceInputBindingUpdateHandlers.ContainsKey(ownerTypeName)) {
commandBindingsCollection.RemoveAt(i); foreach(var handler in instanceInputBindingUpdateHandlers[ownerTypeName]) {
handler.Invoke();
} }
} }
} }
#endregion
/// <summary> /// <summary>
/// Load all registered commands in add-in /// Load all registered commands in add-in
@ -398,15 +638,6 @@ namespace ICSharpCode.Core.Presentation
} }
} }
/// <summary>
/// Register binding owner instance which can be identified by unique name
/// </summary>
/// <param name="contextName">Context class full name</param>
/// <param name="context">Context class instance</param>
public static void LoadContext(string contextName, UIElement context) {
contexts[contextName] = context;
}
/// <summary> /// <summary>
/// Get list of all command bindings which satisfy provided parameters /// Get list of all command bindings which satisfy provided parameters
/// ///
@ -417,12 +648,14 @@ namespace ICSharpCode.Core.Presentation
/// <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 ICollection<CommandBindingInfo> FindCommandBindingInfos(string contextName, UIElement contextInstance, string routedCommandName, string className) { public static ICollection<CommandBindingInfo> FindCommandBindingInfos(string ownerTypeName, Type ownerType, string ownerInstanceName, UIElement ownerInstance, string routedCommandName, string className) {
var foundBindings = new List<CommandBindingInfo>(); var foundBindings = new List<CommandBindingInfo>();
foreach(var binding in commandBindings) { foreach(var binding in commandBindings) {
if((contextName == null || binding.ContextName == contextName) if( (ownerInstanceName == null || binding.OwnerInstanceName == ownerInstanceName)
&& (contextInstance == null || binding.Context == null || binding.Context == contextInstance) && (ownerInstance == null || binding.OwnerInstance == ownerInstance)
&& (ownerTypeName == null || binding.OwnerTypeName == ownerTypeName)
&& (ownerType == null || binding.OwnerType == ownerType)
&& (routedCommandName == null || binding.RoutedCommandName == routedCommandName) && (routedCommandName == null || binding.RoutedCommandName == routedCommandName)
&& (className == null || binding.ClassName == className)) { && (className == null || binding.ClassName == className)) {
@ -434,51 +667,6 @@ namespace ICSharpCode.Core.Presentation
} }
/// <summary>
/// Get list of all command bindings which satisfy provided parameters
///
/// Null arguments are ignored
/// </summary>
/// <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="className">Context class full name</param>
/// <returns>Collection of managed command bindings</returns>
public static CommandBindingCollection FindCommandBindings(string contextName, UIElement contextInstance, string routedCommandName, string className) {
var commandBindingInfos = FindCommandBindingInfos(contextName, contextInstance, routedCommandName, className);
var bindings = new CommandBindingCollection();
foreach(var binding in commandBindingInfos) {
var managedCommandBinding = new ManagedCommandBinding(binding.RoutedCommand);
managedCommandBinding.CanExecute += binding.GeneratedCanExecuteEventHandler;
managedCommandBinding.Executed += binding.GeneratedExecutedEventHandler;
bindings.Add(managedCommandBinding);
}
return bindings;
}
/// <summary>
/// Get list of all input bindings which satisfy provided parameters
///
/// Null arguments are ignored
/// </summary>
/// <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>
public static InputBindingCollection FindInputBindings(string contextName, UIElement contextInstance, string routedCommandName) {
var inputBindingInfos = FindInputBindingInfos(contextName, contextInstance, routedCommandName);
var bindings = new InputBindingCollection();
foreach(var binding in inputBindingInfos) {
foreach(InputGesture bindingGesture in binding.Gestures) {
bindings.Add(new ManagedInputBinding(binding.RoutedCommand, bindingGesture));
}
}
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
@ -489,12 +677,12 @@ namespace ICSharpCode.Core.Presentation
/// <param name="contextInstance">Get gestures assigned only to specific context</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 FindInputGestures(string contextName, UIElement contextInstance, string routedCommandName) { public static InputGestureCollection FindInputGestures(string ownerTypeName, Type ownerType, string ownerInstanceName, UIElement ownerInstance, string routedCommandName) {
var bindings = FindInputBindings(contextName, contextInstance, routedCommandName); var bindings = FindInputBindingInfos(ownerTypeName, ownerType, ownerInstanceName, ownerInstance, routedCommandName);
var gestures = new InputGestureCollection(); var gestures = new InputGestureCollection();
foreach(InputBinding binding in bindings) { foreach(InputBindingInfo bindingInfo in bindings) {
gestures.Add(binding.Gesture); gestures.AddRange(bindingInfo.Gestures);
} }
return gestures; return gestures;
@ -540,5 +728,77 @@ namespace ICSharpCode.Core.Presentation
return registeredCategories; return registeredCategories;
} }
/// <summary>
/// Register default command binding update hander which will keep instance command
/// bindings upated
/// </summary>
/// <param name="commandBindingInfo">Command binding info</param>
private static void RegisterInstaceDefaultCommandBindingHandler(CommandBindingInfo commandBindingInfo)
{
if(commandBindingInfo.DefaultCommandBindingHandler != null) {
commandBindingInfo.DefaultCommandBindingHandler.Invoke();
}
if(commandBindingInfo.OwnerInstanceName != null && commandBindingInfo.OwnerInstance == null) {
RegisterInstanceCommandBindingsUpdateHandler(commandBindingInfo.OwnerInstanceName, commandBindingInfo.DefaultCommandBindingHandler);
} else if(commandBindingInfo.OwnerInstance != null) {
RegisterInstanceCommandBindingsUpdateHandler(commandBindingInfo.OwnerInstance, commandBindingInfo.DefaultCommandBindingHandler);
}
}
/// <summary>
/// Register default command binding update hander which will keep type command
/// bindings upated
/// </summary>
/// <param name="commandBindingInfo">Command binding info</param>
private static void RegisterClassDefaultCommandBindingHandler(CommandBindingInfo commandBindingInfo)
{
if(commandBindingInfo.DefaultCommandBindingHandler != null) {
commandBindingInfo.DefaultCommandBindingHandler.Invoke();
}
if(commandBindingInfo.OwnerTypeName != null && commandBindingInfo.OwnerType == null) {
RegisterClassCommandBindingsUpdateHandler(commandBindingInfo.OwnerTypeName, commandBindingInfo.DefaultCommandBindingHandler);
} else if(commandBindingInfo.OwnerType != null) {
RegisterClassCommandBindingsUpdateHandler(commandBindingInfo.OwnerType, commandBindingInfo.DefaultCommandBindingHandler);
}
}
/// <summary>
/// Register default input binding update hander which will keep instance command
/// bindings upated
/// </summary>
/// <param name="inputBindingInfo">Input binding info</param>
private static void RegisterInstaceDefaultInputBindingHandler(InputBindingInfo inputBindingInfo)
{
if(inputBindingInfo.DefaultInputBindingHandler != null) {
inputBindingInfo.DefaultInputBindingHandler.Invoke();
}
if(inputBindingInfo.OwnerInstanceName != null && inputBindingInfo.OwnerInstance == null) {
RegisterInstanceInputBindingsUpdateHandler(inputBindingInfo.OwnerInstanceName, inputBindingInfo.DefaultInputBindingHandler);
} else if(inputBindingInfo.OwnerInstance != null) {
RegisterInstanceInputBindingsUpdateHandler(inputBindingInfo.OwnerInstance, inputBindingInfo.DefaultInputBindingHandler);
}
}
/// <summary>
/// Register default input binding update hander which will keep type command
/// bindings upated
/// </summary>
/// <param name="inputBindingInfo">Input binding info</param>
private static void RegisterClassDefaultInputBindingHandler(InputBindingInfo inputBindingInfo)
{
if(inputBindingInfo.DefaultInputBindingHandler != null) {
inputBindingInfo.DefaultInputBindingHandler.Invoke();
}
if(inputBindingInfo.OwnerTypeName != null && inputBindingInfo.OwnerType == null) {
RegisterClassInputBindingsUpdateHandler(inputBindingInfo.OwnerTypeName, inputBindingInfo.DefaultInputBindingHandler);
} else if(inputBindingInfo.OwnerType != null) {
RegisterClassInputBindingsUpdateHandler(inputBindingInfo.OwnerType, inputBindingInfo.DefaultInputBindingHandler);
}
}
} }
} }

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

@ -39,8 +39,6 @@ namespace ICSharpCode.Core.Presentation
{ {
var descriptors = AddInTree.BuildItems<CommandBindingDescriptor>(path, caller, false); var descriptors = AddInTree.BuildItems<CommandBindingDescriptor>(path, caller, false);
foreach(var desc in descriptors) { foreach(var desc in descriptors) {
var contextName = !string.IsNullOrEmpty(desc.Context) ? desc.Context : CommandsRegistry.DefaultContextName;
// If routed with such name is not registered register routed command with text same as name // If routed with such name is not registered register routed command with text same as name
if(CommandsRegistry.GetRoutedUICommand(desc.Command) == null) { if(CommandsRegistry.GetRoutedUICommand(desc.Command) == null) {
var commandText = string.IsNullOrEmpty(desc.CommandText) ? desc.Command : desc.CommandText; var commandText = string.IsNullOrEmpty(desc.CommandText) ? desc.Command : desc.CommandText;
@ -48,7 +46,15 @@ namespace ICSharpCode.Core.Presentation
} }
var commandBindingInfo = new CommandBindingInfo(); var commandBindingInfo = new CommandBindingInfo();
commandBindingInfo.ContextName = contextName;
if(!string.IsNullOrEmpty(desc.OwnerInstanceName)) {
commandBindingInfo.OwnerInstanceName = desc.OwnerInstanceName;
} else if(!string.IsNullOrEmpty(desc.OwnerTypeName)) {
commandBindingInfo.OwnerTypeName = desc.OwnerTypeName;
} else {
commandBindingInfo.OwnerTypeName = CommandsRegistry.DefaultContextName;
}
commandBindingInfo.RoutedCommandName = desc.Command; commandBindingInfo.RoutedCommandName = desc.Command;
commandBindingInfo.ClassName = desc.Class; commandBindingInfo.ClassName = desc.Class;
commandBindingInfo.AddIn = desc.Codon.AddIn; commandBindingInfo.AddIn = desc.Codon.AddIn;
@ -60,7 +66,15 @@ namespace ICSharpCode.Core.Presentation
var gestures = (InputGestureCollection)new InputGestureCollectionConverter().ConvertFromString(desc.Gestures); var gestures = (InputGestureCollection)new InputGestureCollectionConverter().ConvertFromString(desc.Gestures);
var inputBindingInfo = new InputBindingInfo(); var inputBindingInfo = new InputBindingInfo();
inputBindingInfo.ContextName = contextName;
if(!string.IsNullOrEmpty(desc.OwnerInstanceName)) {
inputBindingInfo.OwnerInstanceName = desc.OwnerInstanceName;
} else if(!string.IsNullOrEmpty(desc.OwnerTypeName)) {
inputBindingInfo.OwnerTypeName = desc.OwnerTypeName;
} else {
inputBindingInfo.OwnerTypeName = CommandsRegistry.DefaultContextName;
}
inputBindingInfo.AddIn = desc.Codon.AddIn; inputBindingInfo.AddIn = desc.Codon.AddIn;
inputBindingInfo.RoutedCommandName = desc.Command; inputBindingInfo.RoutedCommandName = desc.Command;
inputBindingInfo.Gestures = gestures; inputBindingInfo.Gestures = gestures;
@ -83,10 +97,17 @@ namespace ICSharpCode.Core.Presentation
var descriptors = AddInTree.BuildItems<InputBindingDescriptor>(path, caller, false); var descriptors = AddInTree.BuildItems<InputBindingDescriptor>(path, caller, false);
foreach(var desc in descriptors) { foreach(var desc in descriptors) {
var gestures = (InputGestureCollection)new InputGestureCollectionConverter().ConvertFromString(desc.Gestures); var gestures = (InputGestureCollection)new InputGestureCollectionConverter().ConvertFromString(desc.Gestures);
var contextName = !string.IsNullOrEmpty(desc.Context) ? desc.Context : CommandsRegistry.DefaultContextName;
var inputBindingInfo = new InputBindingInfo(); var inputBindingInfo = new InputBindingInfo();
inputBindingInfo.ContextName = contextName;
if(!string.IsNullOrEmpty(desc.OwnerInstanceName)) {
inputBindingInfo.OwnerInstanceName = desc.OwnerInstanceName;
} else if(!string.IsNullOrEmpty(desc.OwnerTypeName)) {
inputBindingInfo.OwnerTypeName = desc.OwnerTypeName;
} else {
inputBindingInfo.OwnerTypeName = CommandsRegistry.DefaultContextName;
}
inputBindingInfo.AddIn = desc.Codon.AddIn; inputBindingInfo.AddIn = desc.Codon.AddIn;
inputBindingInfo.RoutedCommandName = desc.Command; inputBindingInfo.RoutedCommandName = desc.Command;
inputBindingInfo.Gestures = gestures; inputBindingInfo.Gestures = gestures;

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

@ -5,95 +5,183 @@ using System.Collections.Generic;
namespace ICSharpCode.Core.Presentation namespace ICSharpCode.Core.Presentation
{ {
/// <summary> /// <summary>
/// Stores details about input binding /// Stores details about input binding
/// </summary> /// </summary>
public class InputBindingInfo public class InputBindingInfo
{ {
private UIElement contextInstance; public InputBindingInfo() {
IsModifyed = true;
OldInputBindings = new InputBindingCollection();
NewInputBindings = new InputBindingCollection();
public InputBindingInfo() { Categories = new List<InputBindingCategory>();
ContextName = CommandsRegistry.DefaultContextName; }
Categories = new List<InputBindingCategory>();
}
/// <summary> public string OwnerInstanceName{
/// Context class full name get; set;
/// }
/// Described binding will be valid in this context
/// </summary> private UIElement ownerInstance;
public string ContextName {
get; set;
}
/// <summary> public UIElement OwnerInstance{
/// Context class instance get {
/// if(OwnerInstanceName != null && ownerInstance == null) {
/// Described binding will be valid in this context ownerInstance = CommandsRegistry.GetNamedUIElementInstance(OwnerInstanceName);
/// </summary>
public UIElement Context {
get {
if(contextInstance != null) {
return contextInstance;
} else {
UIElement context;
CommandsRegistry.contexts.TryGetValue(ContextName, out context);
return context;
}
} }
return ownerInstance;
}
set {
ownerInstance = value;
} }
}
public string OwnerTypeName{
get; set;
}
private Type ownerType;
/// <summary> public Type OwnerType {
/// Routed command text set {
/// ownerType = value;
/// Override routed command text when displaying to user
/// </summary>
/// <seealso cref="RoutedCommand"></seealso>
public string RoutedCommandText {
get; set;
} }
get {
if(ownerType == null && OwnerTypeName != null) {
ownerType = Type.GetType(OwnerTypeName);
CommandsRegistry.RegisterNamedUIType(OwnerTypeName, ownerType);
}
return ownerType;
/// <summary>
/// Add-in to which registered this input binding
/// </summary>
public AddIn AddIn {
get; set;
} }
}
/// <summary>
/// Routed command text
///
/// Override routed command text when displaying to user
/// </summary>
/// <seealso cref="RoutedCommand"></seealso>
public string RoutedCommandText {
get; set;
}
/// <summary>
/// Add-in to which registered this input binding
/// </summary>
public AddIn AddIn {
get; set;
}
/// <summary>
/// Gestures which triggers this binding
/// </summary>
public InputGestureCollection Gestures {
get; set;
}
/// <summary>
/// Routed command name
///
/// Described binding triggers this routed command
/// </summary>
/// <seealso cref="RoutedCommand"></seealso>
public string RoutedCommandName {
get; set;
}
/// <summary> /// <summary>
/// Routed command name /// Routed command instance
/// ///
/// Described binding triggers this routed command /// Described binding triggers this routed command
/// </summary> /// </summary>
/// <seealso cref="RoutedCommand"></seealso> /// <seealso cref="RoutedCommandName"></seealso>
public string RoutedCommandName { public RoutedUICommand RoutedCommand {
get; set; get {
return CommandsRegistry.GetRoutedUICommand(RoutedCommandName);
} }
}
private BindingsUpdatedHandler defaultInputBindingHandler;
/// <summary>
/// Default binding update handler update owner or type bindings (depending on input binding info type)
/// so they would always contain latest version
/// </summary>
public BindingsUpdatedHandler DefaultInputBindingHandler
{
get {
if(defaultInputBindingHandler == null && (OwnerTypeName != null || OwnerType != null)) {
defaultInputBindingHandler = delegate {
if(OwnerType != null && IsModifyed) {
GenerateInputBindings();
foreach(ManagedInputBinding binding in OldInputBindings) {
CommandsRegistry.RemoveClassInputBinding(OwnerType, binding);
}
foreach(ManagedInputBinding binding in NewInputBindings) {
CommandManager.RegisterClassInputBinding(OwnerType, binding);
}
IsModifyed = false;
}
};
} else if(defaultInputBindingHandler == null && (OwnerInstanceName != null || OwnerInstance != null)) {
defaultInputBindingHandler = delegate {
if(OwnerInstance != null && IsModifyed) {
GenerateInputBindings();
/// <summary> foreach(ManagedInputBinding binding in NewInputBindings) {
/// Routed command instance OwnerInstance.InputBindings.Remove(binding);
/// }
/// Described binding triggers this routed command
/// </summary> OwnerInstance.InputBindings.AddRange(NewInputBindings);
/// <seealso cref="RoutedCommandName"></seealso>
public RoutedUICommand RoutedCommand { IsModifyed = false;
get { }
return CommandsRegistry.GetRoutedUICommand(RoutedCommandName); };
} }
}
/// <summary> return defaultInputBindingHandler;
/// Gestures which triggers this binding
/// </summary>
public InputGestureCollection Gestures {
get; set;
} }
}
public List<InputBindingCategory> Categories { /// <summary>
get; private set; /// List of categories associated with input binding
/// </summary>
public List<InputBindingCategory> Categories {
get; private set;
}
/// <summary>
/// Indicates whether generated input bindings where modified from last access
/// </summary>
public bool IsModifyed {
get; set;
}
public void GenerateInputBindings()
{
OldInputBindings = NewInputBindings;
NewInputBindings = new InputBindingCollection();
foreach(InputGesture gesture in Gestures) {
var managedInputBinding = new ManagedInputBinding(RoutedCommand, gesture);
NewInputBindings.Add(managedInputBinding);
} }
} }
internal InputBindingCollection OldInputBindings
{
get; set;
}
internal InputBindingCollection NewInputBindings
{
get; set;
}
}
} }

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

@ -140,13 +140,12 @@ namespace ICSharpCode.Core.Presentation
if(!codon.Properties.Contains("command") && (codon.Properties.Contains("link") || codon.Properties.Contains("class"))) { if(!codon.Properties.Contains("command") && (codon.Properties.Contains("link") || codon.Properties.Contains("class"))) {
var commandBindingInfo = new CommandBindingInfo(); var commandBindingInfo = new CommandBindingInfo();
commandBindingInfo.AddIn = codon.AddIn; commandBindingInfo.AddIn = codon.AddIn;
commandBindingInfo.ContextName = CommandsRegistry.DefaultContextName; commandBindingInfo.OwnerTypeName = CommandsRegistry.DefaultContextName;
commandBindingInfo.Class = CommandWrapper.GetCommand(codon, caller, createCommand); commandBindingInfo.Class = CommandWrapper.GetCommand(codon, caller, createCommand);
commandBindingInfo.RoutedCommandName = routedCommandName; commandBindingInfo.RoutedCommandName = routedCommandName;
commandBindingInfo.IsLazy = true; commandBindingInfo.IsLazy = true;
CommandsRegistry.RegisterCommandBinding(commandBindingInfo); CommandsRegistry.RegisterCommandBinding(commandBindingInfo);
CommandsRegistry.InvokeCommandBindingUpdateHandlers(CommandsRegistry.DefaultContextName, null);
} }
if(codon.Properties.Contains("shortcut")) { if(codon.Properties.Contains("shortcut")) {
@ -154,16 +153,19 @@ namespace ICSharpCode.Core.Presentation
var inputBindingInfo = new InputBindingInfo(); var inputBindingInfo = new InputBindingInfo();
inputBindingInfo.AddIn = codon.AddIn; inputBindingInfo.AddIn = codon.AddIn;
inputBindingInfo.Categories.AddRange(CommandsRegistry.RegisterInputBindingCategories("Menu Items")); inputBindingInfo.Categories.AddRange(CommandsRegistry.RegisterInputBindingCategories("Menu Items"));
inputBindingInfo.ContextName = CommandsRegistry.DefaultContextName; inputBindingInfo.OwnerTypeName = CommandsRegistry.DefaultContextName;
inputBindingInfo.RoutedCommandName = routedCommandName; inputBindingInfo.RoutedCommandName = routedCommandName;
inputBindingInfo.Gestures = (InputGestureCollection)new InputGestureCollectionConverter().ConvertFromInvariantString(codon.Properties["gestures"]); inputBindingInfo.Gestures = (InputGestureCollection)new InputGestureCollectionConverter().ConvertFromInvariantString(codon.Properties["gestures"]);
CommandsRegistry.RegisterInputBinding(inputBindingInfo); CommandsRegistry.RegisterInputBinding(inputBindingInfo);
CommandsRegistry.RegisterInputBindingUpdateHandler(CommandsRegistry.DefaultContextName, null, delegate {
var updatedGestures = CommandsRegistry.FindInputGestures(null, null, routedCommandName); BindingsUpdatedHandler gesturesUpdateHandler = delegate {
this.InputGestureText = (string)new InputGestureCollectionConverter().ConvertToInvariantString(updatedGestures); var updatedGestures = CommandsRegistry.FindInputGestures(null, null, null, null, routedCommandName);
}); this.InputGestureText = (string)new InputGestureCollectionConverter().ConvertToInvariantString(updatedGestures);
CommandsRegistry.InvokeInputBindingUpdateHandlers(CommandsRegistry.DefaultContextName, null); };
gesturesUpdateHandler.Invoke();
CommandsRegistry.RegisterClassInputBindingsUpdateHandler(CommandsRegistry.DefaultContextName, gesturesUpdateHandler);
} }
} }
} }

3
src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarButton.cs

@ -50,13 +50,12 @@ namespace ICSharpCode.Core.Presentation
if(!codon.Properties.Contains("command") && (codon.Properties.Contains("link") || codon.Properties.Contains("class"))) { if(!codon.Properties.Contains("command") && (codon.Properties.Contains("link") || codon.Properties.Contains("class"))) {
var commandBindingInfo = new CommandBindingInfo(); var commandBindingInfo = new CommandBindingInfo();
commandBindingInfo.AddIn = codon.AddIn; commandBindingInfo.AddIn = codon.AddIn;
commandBindingInfo.ContextName = CommandsRegistry.DefaultContextName; commandBindingInfo.OwnerTypeName = CommandsRegistry.DefaultContextName;
commandBindingInfo.Class = CommandWrapper.GetCommand(codon, caller, createCommand); commandBindingInfo.Class = CommandWrapper.GetCommand(codon, caller, createCommand);
commandBindingInfo.RoutedCommandName = routedCommandName; commandBindingInfo.RoutedCommandName = routedCommandName;
commandBindingInfo.IsLazy = true; commandBindingInfo.IsLazy = true;
CommandsRegistry.RegisterCommandBinding(commandBindingInfo); CommandsRegistry.RegisterCommandBinding(commandBindingInfo);
CommandsRegistry.InvokeCommandBindingUpdateHandlers(CommandsRegistry.DefaultContextName, null);
} }
if (codon.Properties.Contains("icon")) { if (codon.Properties.Contains("icon")) {

Loading…
Cancel
Save