Tag Archives: csharp

The WPF Version of the Responsive UI Hello World

What is lacking in the first version of the hello world example is the separation of UI and application logic. A refactored WinForms version may be the topic of a future post.

The next step in the discovery of Rx is to create a similar software using WPF. The details can be viewed in the source code, so let’s concentrate on the peculiarities. In this version, pure Rx will be used without ReactiveUI.

wpf version of ui hello world

WPF brings a possibility of total separation of UI, UI logic and application logic. A part of the application can be implemented by bindings to a viewmodel. The viewmodel has to implement the INotifyPropertyChanged interface. We’ll choose the implementation from here for the moment.

The viewmodel is defined as follows, omitting the INotifyPropertyChanged details:

public class MyViewModel : INotifyPropertyChanged
{
    //http://msdn.microsoft.com/en-us/library/ms229614.aspx details ...

    string _CurrentTime;
    public string CurrentTime
    {
        get { return _CurrentTime; }
        private set
        {
            if (value != _CurrentTime)
            {
                _CurrentTime = value;
                NotifyPropertyChanged();
            }
        }
    }

    string _TextInput;
    public string TextInput
    {
        get { return _TextInput; }
        set
        {
            if (value != _TextInput)
            {
                _TextInput = value;
                NotifyPropertyChanged();
                UpdateWordCount();
            }
        }
    }

    private void UpdateWordCount()
    {
        WordCount = TextInput.Split()
            .DefaultIfEmpty()
            .Where(s => s.Trim().Length > 0)
            .Count();
    }

    int _WordCount;
    public int WordCount
    {
        get { return _WordCount; }
        private set
        {
            if (value != _WordCount)
            {
                _WordCount = value;
                NotifyPropertyChanged();
            }
        }
    }

    public MyViewModel()
    {
        Observable.Interval(TimeSpan.FromSeconds(1))
            .Subscribe(_ => CurrentTime = DateTime.Now.ToLongTimeString());
    }
}

By using the separation the application logic becomes testable without building a UI, as the viewmodel is not dependent on System.Windows*.

The word count and the current time field can be bound to the controls by using the standard binding mechanism:

<TextBox ... Text="{Binding CurrentTime}"></TextBox>
<TextBox ... Text="{Binding WordCount}"></TextBox>

However, if we want the word count to be updated on every text change and not after focus change, we’ll have to use the TextChanged of the third text box to update the viewmodel. The update of the word count is currently implemented in the setter for the TextInput property on line 29. Using ReactiveUI this will change as well.

The configuration of the UI by code-behind looks as follows:

ViewModels.MyViewModel VM = new ViewModels.MyViewModel();
DataContext = VM;
var textChanged = Observable.FromEventPattern<TextChangedEventHandler, TextChangedEventArgs>(
    handler => handler.Invoke,
    h => textBox3.TextChanged += h,
    h => textBox3.TextChanged -= h);
textChanged.Subscribe(_ => VM.TextInput = textBox3.Text);

Compared to the first WinForms version it has two responsibilities less – the current time update logic and the word count logic, which is now in the viewmodel.

As the next step, the implementation of the viewmodel should be further simplified.

Source code can be found here.

A Responsive Windows Forms UI using Reactive Extensions

For WPF programming there is a Reactive Extensions extension called ReactiveUI. I like the idea very much, but the last time I have looked at the online documentation, it was slightly out of sync with the current version, and the examples are slightly more elaborate than hello world. I’ll have to return to ReactiveUI at a later point in time.

As it seems, many people still use WinForms. A typical Forms application contains quite a number of event handlers. What Rx promises is a declarative design of your program (UI) logic. Without getting too concerned with lifetime management of this hello world example, here it is:

Responsive WinForms using Rx

The first TextBox gets updated asynchronously with the current time, the second TextBox shows the word count of the text entered in the third TextBox. All that is defined in a single Load event handler, private void Form1_Load(…). You can get the code here.

The initialization of the logic (in Form1_Load) is as follows:

Update textBox1 with the current time asynchronously every second

Observable.Interval(TimeSpan.FromSeconds(1))
          .ObserveOn(this) // scheduled on the Form's scheduler
          .Subscribe(_ => textBox1.Text = DateTime.Now.ToLongTimeString());

No threading code needed :).

Convert an event handler into an observable and set its registration

var textChanged = Observable.FromEventPattern<EventHandler, EventArgs>
 (
  handler => handler.Invoke,
  h => textBox3.TextChanged+= h,
  h => textBox3.TextChanged-= h
 );

Subscribe to the textChanged observable in order to update the word count

textChanged
    .ObserveOn(this) // scheduled on the Form's scheduler
    .Subscribe(x => textBox2.Text =
        textBox3.Text
        .Split()
        .DefaultIfEmpty()
        .Where(s=>s.Trim().Length>0)
        .Count()
        .ToString());

That’s it. No other explicit event handlers, just these observables with lambdas.

Continued here….

Update: Since the original post, a lot has changed. ReactiveUI has a shiny new docs site, a lot of API improvements, and improved exposure.

Asynchronously access an object’s property repeatedly in C#

A question on Stackoverflow got me thinking of a beautiful way of reporting a value of an object in C# repeatedly, something like polling a sensor. Typically, polling is pull-based, but having been reading Intro to Rx for the second time lately, and being convinced of its push-base structural and syntactic eunoia, I’ve created a solution based on Rx listed below.

using System;
using System.Reactive.Concurrency;
using System.Reactive.Linq;

namespace rxtest
{
    class FrequencyMeter
    {
        Random rand = new Random();
        public int Hz
        {
            get { return 60+rand.Next(3); }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var obs = Observable.Generate<FrequencyMeter, int>(
                new FrequencyMeter(), //state
                x => !Console.KeyAvailable, // while no key is pressed
                x => x, // no change in the state
                x => x.Hz, // how to get the value
                x => TimeSpan.FromMilliseconds(250), //how often
                Scheduler.Default)
                .DistinctUntilChanged() //show only when changed
                ;

            using (var _ = obs.Subscribe(x => Console.WriteLine(x)))
            {
                var ticks = Observable.Interval(TimeSpan.FromSeconds(0.5))
                           .Subscribe(x=>Console.WriteLine("tick")); //an example only
                Console.WriteLine("Interrupt with a keypress");
                Console.ReadKey();
            }
        }
    }
}

producing an output similar to that:

Interrupt with a keypress
62
60
62
tick
61
60
tick
62
61
tick
60
62
61
tick
62

Now, with Rx available in C++ that would be interesting what will be left of the eunoia.