Getting Started With Reactive Extensions - Part 2

In this article, we will continue from the previous article and see few examples around UI side. Let us suppose the following snippet, wherein I have simply created one windows form and attached a textbox to it.

  1. using System;    
  2. using System.Reactive.Linq;    
  3. using System.Windows.Forms;    
  4.     
  5. namespace ReactiveExtensions    
  6. {    
  7.     internal class Program    
  8.     {    
  9.         private static void Main(string[] args)    
  10.         {    
  11.            // ObservableGetValue();    
  12.             var textbox = new TextBox();    
  13.             var form = new Form    
  14.             {    
  15.                 Controls = {textbox}    
  16.             };    
  17.     
  18.           Application.Run(form);    
  19.         }    
  20.     
  21.            
  22.         private static void ObservableGetValue()    
  23.         {    
  24.             IObservable<string> obj = Observable.Generate(    
  25.                 0, //Sets the initial value like for loop    
  26.                 _ => true//Don't stop till i say so, infinite loop    
  27.                 i => i + 1, //Increment the counter by 1 everytime    
  28.                 i => new string('#', i), //Append #    
  29.                 i => TimeSelector(i)); //delegated this to private method which just calculates time    
  30.     
  31.             //Subscribe here    
  32.             using (obj.Subscribe(Console.WriteLine))    
  33.             {    
  34.                 Console.WriteLine("Press any key to exit!!!");    
  35.                 Console.ReadLine();    
  36.             }    
  37.         }    
  38.     
  39.         //Returns TimeSelector    
  40.         private static TimeSpan TimeSelector(int i)    
  41.         {    
  42.             return TimeSpan.FromSeconds(i);    
  43.         }    
  44.     }    
  45. }   
Now, with the above change in place, it will simply give me one windows form with one text-box in it.

text box

Now, I would like to listen to text changed event. So, what I would do? I will simply go ahead and attach text changed handler as in the following code snippet.

textchanged

Therefore, it has created the following sample event code.
  1. using System;    
  2. using System.Reactive.Linq;    
  3. using System.Windows.Forms;    
  4.     
  5. namespace ReactiveExtensions    
  6. {    
  7.     internal class Program    
  8.     {    
  9.         private static void Main(string[] args)    
  10.         {    
  11.            // ObservableGetValue();    
  12.             var textbox = new TextBox();    
  13.             var form = new Form    
  14.             {    
  15.                 Controls = {textbox}    
  16.             };    
  17.     
  18.             //Trying to fetch the value from textbox    
  19.             textbox.TextChanged += textbox_TextChanged;    
  20.     
  21.           Application.Run(form);    
  22.         }    
  23.     
  24.         static void textbox_TextChanged(object sender, EventArgs e)    
  25.         {    
  26.             throw new NotImplementedException();    
  27.         }    
  28.     
  29.            
  30.         private static void ObservableGetValue()    
  31.         {    
  32.             IObservable<string> obj = Observable.Generate(    
  33.                 0, //Sets the initial value like for loop    
  34.                 _ => true//Don't stop till i say so, infinite loop    
  35.                 i => i + 1, //Increment the counter by 1 everytime    
  36.                 i => new string('#', i), //Append #    
  37.                 i => TimeSelector(i)); //delegated this to private method which just calculates time    
  38.     
  39.             //Subscribe here    
  40.             using (obj.Subscribe(Console.WriteLine))    
  41.             {    
  42.                 Console.WriteLine("Press any key to exit!!!");    
  43.                 Console.ReadLine();    
  44.             }    
  45.         }    
  46.     
  47.         //Returns TimeSelector    
  48.         private static TimeSpan TimeSelector(int i)    
  49.         {    
  50.             return TimeSpan.FromSeconds(i);    
  51.         }    
  52.     }    
  53. }    
But, if you look at the following screenshot, textchanged is not available.

code

Hence, this won't be helpful for me. Rather than that, I would prefer to have reactive extension and subscribe the same as shown below.
  1. private static void Main(string[] args)    
  2. {    
  3.    // ObservableGetValue();    
  4.     var textbox = new TextBox();    
  5.     var form = new Form    
  6.     {    
  7.         Controls = {textbox}    
  8.     };    
  9.   
  10.     //Using Rx, to get the textchanged     
  11.   
  12.     var textChanged = Observable.FromEventPattern<EventArgs>(textbox, "TextChanged");    
  13.   
  14.     //then, I will subscribe the same     
  15.   
  16.   Application.Run(form);    
  17. }   
Now, if you see the following screenshot, it gave me EventArgs.

EventArgs

really

Here, in order to get changed text, I need to make use of LINQ on the top of Rx. Hence, below is the finished code for the same. I have done little bit of refactoring as well, just to keep the code more readable and clean.
  1. using System;    
  2. using System.Reactive.Linq;    
  3. using System.Windows.Forms;    
  4.     
  5. namespace ReactiveExtensions    
  6. {    
  7.     internal class Program    
  8.     {    
  9.         private static void Main(string[] args)    
  10.         {    
  11.             // ObservableGetValue();    
  12.             GetTextBoxValue();    
  13.         }    
  14.     
  15.         private static void GetTextBoxValue()    
  16.         {    
  17.             var textbox = new TextBox();    
  18.             var form = new Form    
  19.             {    
  20.                 Controls = {textbox}    
  21.             };    
  22.     
  23.             //Using Rx, to get the textchanged     
  24.     
  25.             var textChanged = Observable.FromEventPattern<EventArgs>(textbox, "TextChanged");    
  26.     
  27.             //then, I will subscribe the same using LINQ Projection    
  28.     
  29.             var query = from e in textChanged    
  30.                 select ((TextBox) e.Sender).Text;    
  31.     
  32.             //Hence, if the application quits, i want to unsubscribe    
  33.             using (query.Subscribe(Console.WriteLine))    
  34.             {    
  35.                 Application.Run(form);    
  36.             }    
  37.         }    
  38.     
  39.     
  40.         private static void ObservableGetValue()    
  41.         {    
  42.             IObservable<string> obj = Observable.Generate(    
  43.                 0, //Sets the initial value like for loop    
  44.                 _ => true//Don't stop till i say so, infinite loop    
  45.                 i => i + 1, //Increment the counter by 1 everytime    
  46.                 i => new string('#', i), //Append #    
  47.                 i => TimeSelector(i)); //delegated this to private method which just calculates time    
  48.     
  49.             //Subscribe here    
  50.             using (obj.Subscribe(Console.WriteLine))    
  51.             {    
  52.                 Console.WriteLine("Press any key to exit!!!");    
  53.                 Console.ReadLine();    
  54.             }    
  55.         }    
  56.     
  57.         //Returns TimeSelector    
  58.         private static TimeSpan TimeSelector(int i)    
  59.         {    
  60.             return TimeSpan.FromSeconds(i);    
  61.         }    
  62.     }    
  63. }  
Hence, with the above change in place, when I run the app, it will give us the following output.

run the app

You can also download the source code from here.

With this I would like to wrap this session here. Thanks for joining me.