Toujours dans l’optique de bien respecter ce merveilleux modèle MVVM dans le cadre de nos développements WPF, je vous propose aujourd’hui une extension pour les fenêtres (type Window) permettant d’associer à des raccourcis clavier des commandes de votre ViewModel par simple Binding dans le code XAML.
J’ai nommé cette extension : WindowExtensions. Le tout tient dans un fichier car je n’ai pas trouvé utile de créer un projet pour si peu de code.
Le fichier WindowExtensions.cs
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Input;
namespace Dotnetnews.Extensions
{
class ShortcutCommand : DependencyObject
{
public Key Key { get; set; }
public ModifierKeys ModifierKeys { get; set; }
public static readonly DependencyProperty CommandProperty =
DependencyProperty.Register("Command", typeof(ICommand), typeof(ShortcutCommand), new PropertyMetadata(null));
public ICommand Command
{
get { return (ICommand)GetValue(CommandProperty); }
set { SetValue(CommandProperty, value); }
}
public static readonly DependencyProperty CommandParameterProperty =
DependencyProperty.Register("CommandParameter", typeof(object), typeof(ShortcutCommand), new PropertyMetadata(null));
public object CommandParameter
{
get { return (object)GetValue(CommandParameterProperty); }
set { SetValue(CommandParameterProperty, value); }
}
}
class ShortcutCommandCollection : Collection<ShortcutCommand>
{
}
class WindowExtensions
{
public static readonly DependencyProperty GlobalShortcutsProperty =
DependencyProperty.RegisterAttached("GlobalShortcuts", typeof(ShortcutCommandCollection),
typeof(WindowExtensions),
new FrameworkPropertyMetadata(null,
GlobalShortcutsPropertyChanged));
public static ShortcutCommandCollection GetGlobalShortcuts(UIElement window)
{
return (ShortcutCommandCollection)window.GetValue(GlobalShortcutsProperty);
}
public static void SetGlobalShortcuts(UIElement window, ShortcutCommandCollection shortcuts)
{
window.SetValue(GlobalShortcutsProperty, shortcuts);
}
private static void GlobalShortcutsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var window = (Window)d;
window.PreviewKeyDown += WindowPreviewKeyDown;
}
private static void WindowPreviewKeyDown(object sender, KeyEventArgs e)
{
var window = (Window)sender;
var shortcuts = GetGlobalShortcuts(window);
var sc =
shortcuts.SingleOrDefault(
s => s.Key == e.Key && ((Keyboard.Modifiers & s.ModifierKeys) == s.ModifierKeys));
if (sc != null && sc.Command != null)
{
if (sc.Command.CanExecute(sc.CommandParameter))
sc.Command.Execute(sc.CommandParameter);
}
}
}
}
Cadre d’utilisation dans notre code XAML
<Window x:Class="MyApplication.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ViewModels="clr-namespace:MyApplication.ViewModels"
xmlns:DnE="clr-namespace:Dotnetnews.Extensions"
DataContext="{DynamicResource ViewModel}">
<Window.Resources>
<ViewModels:MainViewModel x:Key="ViewModel" />
</Window.Resources>
<DnE:WindowExtensions.GlobalShortcuts>
<DnE:ShortcutCommandCollection>
<!-- Raccourci clavier Ctrl+R -->
<DnE:ShortcutCommand Key="R" ModifierKeys="Control"
Command="{Binding RefreshCommand, Source={StaticResource ViewModel}}" />
</DnE:ShortcutCommandCollection>
</DnE:WindowExtensions.GlobalShortcuts>
...
</Window>
Note : Il est important de placer le code de GlobalShortcuts après le code des ressources contenant le ViewModel.
Aucun commentaire pour le moment. Soyez le/la premi(er/ère).