问题
I have a form that should capture KeyDown/KeyUp events.
This code fails with NRE, because it looks for KeyDown control on my current view:
this.BindCommand(ViewModel, vm => vm.KeyDown, "KeyDown");
What I've done is created wrapper class that has form as a property, so I can use this overload:
this.BindCommand(ViewModel, vm => vm.KeyDown, v => v.Form, "KeyDown");
While it works, it seems like a hack to me. Is there a proper way to bind to local events?
回答1:
That's the right way to do it if you're using BindCommand. If you want to get rid of the string and you're using ReactiveUI.Events, you could also do:
this.Form.Events().KeyDown
.InvokeCommand(this, x => x.ViewModel.KeyDown);
As an aside, "KeyDown" isn't a very MVVM'y command. I'd write your key => command mappings at the View layer, like this (coding via TextArea, ignore syntax bugs):
this.Form.Events().KeyDown
.Where(x => x.Key == Key.C && (x.Modifier & Modifier.Ctrl))
.InvokeCommand(this, x => x.ViewModel.CopyText;
回答2:
I realize I'm really late to this particular party, but since I've been working on something similar, this is the approach I took, based on Paul's advice:
var keyDownSub= Observable.FromEventPattern<KeyEventHandler, KeyEventArgs>(
ev => txtbxCommandLine.KeyDown += ev,
ev => txtbxCommandLine.KeyDown -= ev
).Select(x => x.EventArgs)
.Where(x =>
x.KeyCode.ToString().ToUpper().Equals("RETURN")
&& (_returnKeyPressed || x.Alt || x.Control))
.InvokeCommand(_mainViewModel.ProcessCommandLine);
This seems to work perfectly fine in WinForms, if it is a bit more verbose than it would be in WPF.
来源:https://stackoverflow.com/questions/22485360/how-can-i-bind-a-command-to-a-local-event