Using Xamarin Forms 4.0 with the new Shell feature, I have a button on a page .Let's call this page the Start Page.
When I press the button the user is navigated to a Second Page using Shell.Current.GoToAsync
.
When the user later navigates back to the Start Page the button is now deactiviated. But why?
Here is the code in the view model:
public class SomeViewModel : ReactiveObject
{
private ReactiveCommand<Unit, Unit> _someCommand;
public ReactiveCommand<Unit, Unit> SomeCommand
{
get => _someCommand;
set => this.RaiseAndSetIfChanged(ref _someCommand, value);
}
public SomeViewModel
{
SomeCommand = ReactiveCommand.CreateFromTask<Unit>(async x =>
{
await Shell.Current.GoToAsync("//Root/SomePage");
}).Subscribe();
}
By trial and error, I found a solution.
Specifically, by making the following change to the definition of SomeCommand, the button will no longer be disabled when the user returns to the Start Page:
[...]
SomeCommand = ReactiveCommand.CreateFromTask<Unit>(async x =>
{
await Task.CompletedTask;
})
.Select(_ => Observable.FromAsync(() => Shell.Current.GoToAsync("//Root/SomePage")}")))
.Concat()
.Subscribe();
[...]
Can anyone expain what is going on here? Why does the first approach not work, and why does the second approach work? To me the two approaches look more or less identical.
I'm using ReactiveUI version v9.17.4. So far I've only tested this on iOS.
UPDATE: Turned out to be a threading issue.
CreateFromObservable
instead is using select and stuff. I strongly suspect you got a threading issue happening there. – Glenn WatsonCreateFromObservable
is a nice simplification, that I was not aware of. However, it yields the same issue with the button becoming disabled as the first approach, so it will not work here. I agree that a threading issue could be the issue. I will try and investigate some more. – 1iveowl