Sharpnado.Tabs
Sharpnado.Tabs copied to clipboard
[Xamarin.Forms] Is there a way to cancel a tab switch after clicking a selectable tab?
Given this UI:
<tabs:ViewSwitcher x:Name="Switcher"
SelectedIndex="{Binding SelectedViewModelIndex, Mode=TwoWay}">
...some views
</tabs:ViewSwitcher>
and
<tabs:TabHostView x:Name="TabHost"
TabType="Fixed"
SelectedIndex="{Binding Source={x:Reference Switcher}, Path=SelectedIndex, Mode=TwoWay}">
<tabs:TabHostView.Tabs>
... some tabs
</tabs:TabHostView.Tabs>
</tabs:TabHostView>
and this view model implementation:
public int SelectedViewModelIndex
{
get => selectedViewModelIndex;
set
{
if (ShouldChangePage(from: selectedViewModelIndex, to: value)){
SelectedViewModelIndex = value;
}{
// Don't want to change tab if I get here
}
}
}
Even if the pseudo "ShouldChangePage" method returns false, and we never actually set the SelectedViewModelIndex property - the UI switches tabs anyway even though the selectedViewModelIndex doesn't change.
I could utilise IsEnabled and pre-disable the tabs based on my logic - but I would like to perform an action based on a tab click like show some UI with "why can't you switch" type explanation.
Is there any way to do this?
Looking into the source, It appears that OnTabItemTapped is always called and the selected index always changed in TabHostView whenever an item is tapped and IsSelectable is true. And this is what drives the tab to change. The view model index is just reacting to that property, and not changing it doesn't affect the underlying view's new tab index. So I don't think there is any way to do this without using IsSelectable and pre-calculating the selectable status. Would I be correct @roubachof ?And would you consider a PR to add an event to be raised when a user clicks a "non-selectable" tab so I could perform some action without the UI changing?
I found that clearing the Effects for the tabitem in the TabHostView.Tabs array blocks navigating to the tab and allows any GestureRecognizers on that tabitem to work. This is because when you click on a selectable tab it adds the effect https://github.com/roubachof/Sharpnado.Tabs/blob/5ff429bfce07fe7d3f485154b13663ebd3ac828e/Tabs/Tabs/TabHostView.cs#L703 but never clears them. So if you make the tab to IsSelectable = false you will have to manually clear those effects to get it to not navigate.
Also if you want to which that tab back to IsSelectable = true you need to trigger UpdateSelectableTabs to get the proper behavior. The easiest way I got it to do that was just to change the orientation and change it back in the next line to the original value. It doesn't show any UI flickering when you do that thankfully. Hope that helps anyone in the future.