How would you close a modal dialog with events? Easy. Create the following KeyDown and ButtonClick events.
event | action | returns |
---|---|---|
VirtualKey.Enter | Close | true |
VirtualKey.Escape | Close | false |
ButtonOK.Click | Close | true |
ButtonCancel.Click | Close | false |
And that is perfectly OK! But you’re here to learn how to do this with Rx (Reactive Extensions). Let’s see how this would work. Start by creating an Observable that pushes KeyDownEvents:
var keys = Observable.FromEventPattern<TypedEventHandler<CoreWindow, KeyEventArgs>, KeyEventArgs>(
h => Window.Current.CoreWindow.KeyDown += h,
h => Window.Current.CoreWindow.KeyDown -= h)
.Select(pattern => pattern.EventArgs);
Then you create two Observables that pushes ButtonClicks for OK and Cancel:
var okClicks = Observable.FromEventPattern<RoutedEventHandler, RoutedEventArgs>(
h => ButtonOK.Click += h,
h => ButtonOK.Click -= h);
var cancelClicks = Observable.FromEventPattern<RoutedEventHandler, RoutedEventArgs>(
h => ButtonCancel.Click += h,
h => ButtonCancel.Click -= h);
Now merge these streams and subscribe to them. For the Enter and OK Button, pass true to the Close method:
keys.Where(x => x.VirtualKey == VirtualKey.Enter)
.Select(_ => true).Merge(okClicks.Select(_ => true))
.Subscribe(Close);
And pass false to the Close method for Escape and the Cancel button:
Add(keys.Where(x => x.VirtualKey == VirtualKey.Escape)
.Select(_ => false).Merge(cancelClicks.Select(_ => false))
.Subscribe(Close);
The actual Close method is simplified for this example. Usually you’d write some logic to close a window or popup. Here only the intended action is shown:
private void Close(bool result) {
Info.Text = "Window close action: " + result;
HiddenTextBoxJustToGetTheFocusAwayFromTheClickedButton.Focus(FocusState.Programmatic);
}
Don’t forget to dispose the subscriptions. The OnNavigatingFrom in MainPage.xaml.cs in the demo project will show you how.