使用MVVM模式,我如何处理按键手势?UserControl。InputBindings无法工作,因为它不可聚焦。我已经定义了一个ICommand,当键入正确的键时应该调用它,但是我不知道如何将该命令与视图连接起来。谢谢Stefan
r1zk6ea11#
我通过创建一个DelegateCommand类解决了这个问题,它看起来和RelayCommand(见Josh Smith)完全一样,只是它允许更新回调。
public class DelegateCommand : ICommand { Action<object> _execute; Predicate<object> _canExecute; #region Constructors public DelegateCommand() { } public DelegateCommand(Action<object> execute) : this(execute, null) { } public DelegateCommand(Action<object> execute, Predicate<object> canExecute) { if (execute == null) throw new ArgumentNullException("execute"); _execute = execute; _canExecute = canExecute; } #endregion // Constructors public void Delegate(Action<object> execute) { _execute = execute; } public void Delegate(Action<object> execute, Predicate<object> canExecute) { _execute = execute; _canExecute = canExecute; } #region ICommand Members [DebuggerStepThrough] public bool CanExecute(object parameter) { return _canExecute == null ? _execute != null : _canExecute(parameter); } public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } public void Execute(object parameter) { if (CanExecute(parameter)) _execute(parameter); } #endregion // ICommand Members }
然后我创建了一个类来保存静态应用程序命令。
public class CustomCommands { private readonly static DelegateCommand admin; static CustomCommands() { admin = new DelegateCommand(); } public static DelegateCommand AdminCommand { get { return admin; } } }
然后,我添加了一个键绑定到主窗口,因为用户控件不接收键手势。
<Window.InputBindings> <KeyBinding Key="A" Modifiers="Control" Command="my:CustomCommands.AdminCommand"/> </Window.InputBindings>
然后,在我的ViewModel中,我可以像这样处理事件:
public class OfflineViewModel : ViewModelBase { public OfflineViewModel() { CustomCommands.AdminCommand.Delegate(ShowAdmin); } public override void Removed() { base.Removed(); ReleaseAdminCommand(); } public override void Hidden() { base.Hidden(); ReleaseAdminCommand(); } void HookAdminCommand() { CustomCommands.AdminCommand.Delegate(ShowAdmin); } void ReleaseAdminCommand() { // Remove handling CustomCommands.AdminCommand.Delegate(null, null); } void ShowAdmin(object parameter) { Navigation.Push(new AdminViewModel()); } }
我可以选择使用DelegateCommand中的事件。
xxb16uws2#
这对我有用(.Net 4. 0)
<UserControl> <UserControl.InputBindings> <KeyBinding Gesture="CTRL+C" Command="{Binding CancelCommand}" /> <KeyBinding Gesture="F5" Command="{Binding StartCommand}" /> <KeyBinding Gesture="CTRL+F5" Command="{Binding FreshStartCommand}" /> <KeyBinding Gesture="F10" Command="{Binding ContinueCommand}" /> <KeyBinding Gesture="F9" Command="{Binding RepeatCommand}" /> <KeyBinding Gesture="ALT+F4" Command="{Binding CloseCommand}" /> <KeyBinding Gesture="CTRL+N" Command="{Binding NewUUTCommand}" /> </UserControl.InputBindings> .... <StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal" HorizontalAlignment="Center"> <Button x:Name="BtnStart" Content="STARTEN" Command="{Binding StartCommand}"/> <Button Content="STOP" Command="{Binding StopCommand}"/> </StackPanel> .... <FocusManager.FocusedElement> <Binding ElementName="BtnStart"/> </FocusManager.FocusedElement> </UserControl>
诀窍是确保焦点被设置到UserControl中。对我来说,这不是自动发生的。一旦焦点被设置,KeyBinding就工作了。(注意焦点被设置在元素的最后,因为元素必须首先定义)为了完整起见,下面是ViewModel代码。
public ICommand StartCommand { get { if (this._startCommand == null) { this._startCommand = new Mvvm.RelayCommand(parm => DoStart(), parm => DoCanStart()); } return this._startCommand; } } private bool DoCanStart() { return !IsRunning && ReadyToRun; } private void DoStart() { log.Debug("Start test"); ... }
egdjgwm83#
看这个例子:https://thomaslevesque.com/2009/03/17/wpf-using-inputbindings-with-the-mvvm-pattern/它使用XML标记将其绑定到DataContext of the root element。希望对您有所帮助。此解决方案有一个局限性:它只对XAML根的DataContext有效。因此,例如,您不能使用它在DataContext也被重定义的控件上定义InputBinding,因为标记扩展将访问根DataContext。
DataContext of the root element
3条答案
按热度按时间r1zk6ea11#
我通过创建一个DelegateCommand类解决了这个问题,它看起来和RelayCommand(见Josh Smith)完全一样,只是它允许更新回调。
然后我创建了一个类来保存静态应用程序命令。
然后,我添加了一个键绑定到主窗口,因为用户控件不接收键手势。
然后,在我的ViewModel中,我可以像这样处理事件:
我可以选择使用DelegateCommand中的事件。
xxb16uws2#
这对我有用(.Net 4. 0)
诀窍是确保焦点被设置到UserControl中。对我来说,这不是自动发生的。一旦焦点被设置,KeyBinding就工作了。(注意焦点被设置在元素的最后,因为元素必须首先定义)
为了完整起见,下面是ViewModel代码。
egdjgwm83#
看这个例子:https://thomaslevesque.com/2009/03/17/wpf-using-inputbindings-with-the-mvvm-pattern/
它使用XML标记将其绑定到
DataContext of the root element
。希望对您有所帮助。此解决方案有一个局限性:它只对XAML根的DataContext有效。因此,例如,您不能使用它在DataContext也被重定义的控件上定义InputBinding,因为标记扩展将访问根DataContext。