I've just started looking into ReactiveUI and I guess I'm missing something. Say I have a 'Connect' button and want to create a new network connection based on the server address in a TextBox. I thought, I'd create a ReactiveCommand and bind it to the Button, then do something like WithLatestFrom with the value of the server address property (that's how I've done it in Java or Typescript).
However I can't find the right syntax. Can anyone elaborate?
BR,
Daniel
Asked
Active
Viewed 93 times
0

Daniel
- 597
- 11
- 19
2 Answers
2
Ok my friend, if I understood you should do something like this:
First your ViewModel, you want to derive from ReactiveObject in order to get access to this.RaiseAndSetIfChanged(...) wichs triggers INotifyPropertyChanged
public class MainViewModel : ReactiveObject
{
private string _connectionUrl;
public string ConnectionUrl
{
get => _connectionUrl;
set => this.RaiseAndSetIfChanged(ref _connectionUrl, value);
}
public ReactiveCommand ConnectCommand { get; set; }
public MainViewModel()
{
ConnectCommand = ReactiveCommand.Create(() =>
{
//your logic goes here...
System.Diagnostics.Debug.WriteLine("Button Pressed");
System.Diagnostics.Debug.WriteLine($"{ConnectionUrl}");
});
}
}
Next thing to do is wire your View and your ViewModel via view's DataContext
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new MainViewModel();
}
}
And of course the required XAML to bind controls to properties and commands
<Window x:Class="WPFRx.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPFRx"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<StackPanel HorizontalAlignment="Center"
VerticalAlignment="Center">
<TextBox x:Name="Connection"
Text="{Binding ConnectionUrl, Mode=TwoWay}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Width="200"/>
<Button x:Name="BtnConnect"
Content="Connect"
Command="{Binding ConnectCommand}"/>
</StackPanel>
</Window>
I hope this helps you, regards.

Adrián Romero
- 620
- 7
- 17
-
this helped you ? – Adrián Romero Mar 16 '18 at 22:39
-
Maybe Im wrong but I think this line: "public ReactiveCommand ConnectCommand { get; set; }" should be "public ReactiveCommand
ConnectCommand { get; }". You dont want to expose the ReactiveCommand as a "read/write" property, it is better to declare as readonly property. – Luis Apr 15 '18 at 01:52 -
Good one, you are right. It would be better as readonly property, also the reactiveui band recommends _ReactiveCommand
_ – Adrián Romero Apr 15 '18 at 02:01
1
The adrian answer is fine, I'll add some code to help a little bit more:
public class MainViewModel : ReactiveObject
{
private string connectionUrl;
// constructor
public MainViewModel()
{
// maybe you need to disable the button if the textbox is empty
// ypu can create an observable to check if ConnectionUrl is null or empty
var canConnect = this.WhenAnyValue(x => x.ConnectionUrl)
.Where(conn => !string.IsNullOrEmpty(conn);
// use "ReactiveCommand.CreateFromTask" if you need asynchronous operations.
ConnectCommand = ReactiveCommand.Create(() =>
{
// you can use the ConnectionUrl property here, for example
var dbConnection = new DbConnection(ConnectionUrl);
}, canConnect); // <-- we are telling to the command when will be enabled
}
// this property will be binded to the textbox
public string ConnectionUrl
{
get => connectionUrl;
set => this.RaiseAndSetIfChanged(ref connectionUrl, value);
}
// this command will be binded to the button
public ReactiveCommand ConnectCommand { get; }
}

Luis
- 436
- 4
- 11