If you are working on XAML in C#, you must know the MVVM pattern. To achieve this, to make the View “react” to the changes in ViewModel, one of the best ways is using ReactiveUI.
This entry is about some reactive ways to bind your data.
One Way Bind
Sets up a one-way binding from a property on the ViewModel to the View.
this.OneWayBind(ViewModel, viewModel => viewModel.Name, view => view.Name.Text); // or likes this this.WhenAnyValue(x => x.ViewModel.Name).BindTo(this, view => view.Name.Text);
Two Ways Bind
Sets up a two-way binding between a property on the ViewModel to the View.
this.Bind(ViewModel, viewModel => viewModel.Name, view => view.Name.Text); // We can choose when to update this.Bind(ViewModel, viewModel => viewModel.SomeProperty, view => view.SomeTextBox, SomeTextBox.Events().LostKeyboardFocus);
Bind an ICommand to a control, or to a specific event on that control (how this is implemented depends on the UI framework):
// Bind the OK command to the button. this.BindCommand(ViewModel, viewModel => viewModel.OkCommand, view => view.OkButton); // Bind the OK command to when the user presses a key this.BindCommand(ViewModel, viewModel => viewModel.OkCommand, view => view.RootView, "KeyUp"); // Invoke a command whenever the Escape key is pressed this.Events().KeyUpObs .Where(x => x.EventArgs.Key == Key.Escape) .InvokeCommand(this, x => x.ViewModel.Cancel); // Subscribe to Cancel, and close the Window when it happens this.WhenAnyObservable(x => x.ViewModel.Cancel).Subscribe(_ => this.Close()); // or the short way ViewModel.Cancel.Subscribe(_ => this.Close());
Data Type Conversion
We can use expression to convert one data type to another.
// Age is an integer, Text is a string // In the last parameter, we .ToString() the integer this.OneWayBind(ViewModel, viewModel => viewModel.Age, view => view.Name.Text, value => value.ToString());
Power of BindTo
With normal binding, the source of updating are the changes of binding property. That means for every change, the binding properties will be updated.
But with BindTo, we can decide WHEN and HOW.
// we can literary bind anything to anything // only need some expressions this.WhenAnyValue(x => x.SomeList.TotalAmount) .Select(x => x > 50) // WHEN .Select(x => x.ToString("N2") // HOW .BindTo(this, x => x.ViewModel.DisplayAmount);
The interest thing about BindTo is it can make a binding between 2 view models:
ViewOne.WhenAnyValue(v1 => v1.ViewModel.Name) .BindTo(ViewTwo, v2 => v2.ViewModel.Name)