Question

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?

Was it helpful?

Solution

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;

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top