📜 ⬆️ ⬇️

LINQ to Events - declarative work with asynchronous interface

I came across a very interesting LINQ extension that allows you to work declaratively with an asynchronous interface ( themechanicalbride.blogspot.com/2009/07/introducing-rx-linq-to-events.html ). The extension now exists as part of the Silverlight Toolkit (Rx framework), but will later become part of .NET 4.0 (System.Reactive.dll).

The idea is to erase the boundaries between IEnumerable and IObservable interfaces (read between Iterator and Observer patterns). Asynchronous events are represented as a sequence of data returned as if by a yield return. And this in turn allows you to work with this sequence through LINQ in a functional, declarative style.

For example, you can use LINQ to formulate drag and drop controls:
')
IObservable < Event < MouseEventArgs >> draggingEvent =
from mouseLeftDownEvent in control.GetMouseLeftDown()
from mouseMoveEvent in control.GetMouseMove().Until(control.GetMouseLeftUp())
select mouseMoveEvent;


The expression reads as follows: for each click on the left mouse button, to receive each mouse move event until the left mouse button is pressed.

Thus from allows to declaratively describe the sequence of events. Otherwise, it would be necessary to create a state machine and set the flag of clicking on the left mouse button. And in the handler for moving the mouse, test this flag and change the behavior of the handler depending on it. Using the Rx framework allows you to describe the sequence of events declaratively and not to introduce additional variables.

Similarly, it is possible to test the GUI where transitions from state to state are not instantaneous, but occur with animation, the end of which must be waited before making references to the control properties.

Rating rating = new Rating ();
IObservable < Unit > test =
ObservableExtensions
.DoAsync(() => TestPanel .Children.Add(rating)) //
.WaitFor( TestPanel .GetLayoutUpdated()) //
.DoAsync(() => rating.Value = 1.0) //
.WaitFor(
rating
.GetActualValueChanged() //
.SkipWhile(actualValueChangedEvent => //
actualValueChangedEvent.EventArgs.NewValue != rating.Value))
.Assert(() => rating.GetRatingItems().Last().ActualValue == 1.0); // Assert

//
test.Subscribe(() => TestPanel .Children.Remove(rating));


The author of the original post promises in the near future to highlight cross-threaded interaction using this framework.

Areas of use



WPF Adaptation


silverlight.codeplex.com/SourceControl/ListDownloadableCommits.aspx
evain.net/blog/articles/2009/07/30/rebasing-system-reactive-to-the-net-clr

It looks like there are no code branches adapted for WPF yet, but they promise to add in .NET 4.0. However, now you can take raws and pick it up manually.

Bindable LINQ


The development of the idea - the implementation of the binding to the declaratively described chains of events. When a dependent property changes, the GUI is redrawn to reflect the changes. This is not the case in Rx now. However, a similar connection with INotifyPropertyChanged is in the following projects (the projects themselves have not yet looked):

Source: https://habr.com/ru/post/67814/


All Articles