Events¶
A view raises events: a button is clicked, a key is released, a page loads. To use them in a view model pipeline, you turn each event into a stream. Then you can filter it, combine it with other streams, and feed it to a command.
Generate a stream for every event¶
The ReactiveUI.Primitives.ObservableEvents package does this for you. It is a source generator: a part of the
compiler that writes extra C# code into your project when it builds. For every public event on a type, it writes a
strongly typed stream, so your IDE suggests the events and the compiler checks their names. Call Events() on the
object that raises the event, then pick the event as a property on the result.
ObservableEvents is the full walkthrough: installing the package, what each event's stream sends, static events, and the compiler warning the generator reports when it cannot see an event.
Use a generated stream in a view¶
Because each event is a stream, an operator can filter or combine it the way it would any other stream: buffering a
run of key presses, say, or selecting only the argument a command needs. Subscribe inside
WhenActivated so the subscription starts when the view appears and stops when it is hidden;
otherwise the view or its view model can outlive the other. InvokeCommand runs a ReactiveCommand each time the
stream emits, which is the usual way to connect a button's click stream to a view model command. See
Composing events for a worked example, and
the operator pages for Buffer, Select, Where and the rest.
Turn an event into a stream yourself¶
Without the generator, Signal has two methods that do the same job by hand. Each takes a lambda that attaches the
handler and one that removes it.
Signal.FromEventPatternworks with events whose delegate takes a sender and anEventArgs. It sends anEventPattern<TEventArgs>, withSenderandEventArgsproperties.Signal.FromEventworks with any delegate type, including one that carries noEventArgsat all.
Neither method looks events up by name, so both work with trimming and Native AOT. See From an event for both methods, their overloads, and the conversion argument a custom delegate type needs.