Reputation: 151
I have a simple demo application with ReactiveUI:
//in the viewmodel
class MainViewModel : ReactiveObject
{
public ReactiveUI.ReactiveCommand<Unit, Unit> MyReactiveCommand { get; }
public MainViewModel()
{
MyReactiveCommand = ReactiveCommand.Create(() => { MessageBox.Show("Hello"); }, outputScheduler: RxApp.MainThreadScheduler);
}
}
In the view XAML
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
<Grid>
<WrapPanel HorizontalAlignment = "Left">
<Button Content="button" Command="{Binding MyReactiveCommand}"/>
</WrapPanel>
</Grid>
When you press the button there should be a Message Box but instead I get the following error:
System.InvalidOperationException: 'The calling thread cannot access this object because a different thread owns it.'
I have tried returning a value and then subscribing like Glenn suggested but that had the same problem. At least with this code the Message Box opens before it crashes ;)
public class MainViewModel : ReactiveObject
{
public ReactiveCommand<Unit, Unit> MyReactiveCommand { get; }
public MainViewModel()
{
MyReactiveCommand = ReactiveCommand.CreateFromObservable(DoSometing);
MyReactiveCommand.Subscribe(x => { MessageBox.Show("Hello"); });
}
public IObservable<Unit> DoSometing()
{
return Observable.Start(() => { });
}
}
Upvotes: 0
Views: 647
Reputation: 2888
So a couple things to be aware of. ReactiveCommand.CreateFromObservable
has a parameter called outputScheduler
and this will be where the Subscribe's output will go to. You can pass RxApp.MainThreadScheduler
here.
public class MainViewModel : ReactiveObject
{
public ReactiveCommand<Unit, Unit> MyReactiveCommand { get; }
public MainViewModel()
{
MyReactiveCommand = ReactiveCommand.CreateFromObservable(DoSometing, outputScheduler: RxApp.MainThreadScheduler);
MyReactiveCommand.Subscribe(x => { MessageBox.Show("Hello"); });
}
public IObservable<Unit> DoSometing()
{
return Observable.Start(() => { });
}
}
Note also make sure you have installed the NuGet package ReactiveUI.WPF
Upvotes: 1