Reputation: 41
I use MVVM for my App and want to achive to change the visibility of my TabBarItems after i presed a Login Button. But I dont know what the best practice is.
I have a TabBar in my AppShell which looked like this
<ShellContent
Title="Tab1"
Icon="tab1.svg"
ContentTemplate="{DataTemplate local:TabOneView}"
Route="TabOne">
</ShellContent>
<ShellContent
Title="Login"
Icon="login.svg"
IsVisible="{Binding LoginIsVisible}"
ContentTemplate="{DataTemplate local:LoginView}"
Route="Login">
</ShellContent>
<ShellContent
Title="Tab3"
Icon="Tab3.svg"
IsVisible="{Binding Tab3IsVisible}"
ContentTemplate="{DataTemplate local:TabThreeView}"
Route="TabThree">
</ShellContent>
Tab3 should not be visible at the start. And the LoginTab should be visible. Should I assign the visibility in the code behind from the AppShell or is there a better way for MVVM?
Now I have the View and ViewModel for for my Login
<VerticalStackLayout>
<Button
Margin="0,20,0,0"
BackgroundColor="#0074BA"
HeightRequest="60" Text="Login"
TextColor="White" Command="{Binding LoginCommand}">
<Button.Triggers>
<Trigger TargetType="Button" Property="IsFocused" Value="True">
<Setter Property="BackgroundColor" Value="Grey"/>
</Trigger>
</Button.Triggers>
</Button>
</VerticalStackLayout>
namespace MyApp.ViewModels
{
public partial class LoginViewModel : BaseViewModel
{
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(LoginCommand))]
public string? user;
public LoginViewModel()
{
}
private bool CanLogin(object obj)
{
return User!= null
&& User!= string.Empty;
}
[RelayCommand(CanExecute = nameof(CanLogin))]
private async Task Login(object obj)
{
}
}
}
Now when I press the Login button the LoginView should not be visible and the Tab3 should be. Hope you can give me some advice. Thanks :-)
Upvotes: 0
Views: 184
Reputation: 41
I have now a different approach. After I clicked the Login Button I load the AppShell again with different visibility settings.
In my LoginViewModel
[RelayCommand(CanExecute = nameof(CanLogin))]
private async Task Login(object obj)
{
await Task.Run(() =>
{
if (Application.Current != null)
{
// Reload the AppShell
Application.Current.MainPage = new AppShell(new AppShellViewModel(true));
}
});
}
In my AppShellViewModel
public AppShellViewModel(bool login)
{
// Check if user made a login
if (login)
{
// Set Visibility Propertys
}
}
Upvotes: 0
Reputation: 4302
You can refer to this following code:
Create MAUI project and then add LoginPage and NewPage1 to root directory, also ViewModels folder within LoginViewModel:
LoginPage like this:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiApp5.LoginPage"
Title="LoginPage">
<VerticalStackLayout>
<Label
Text="Welcome to .NET MAUI!"
VerticalOptions="Center"
HorizontalOptions="Center" />
<Button Text="Login"
Command="{Binding LoginCommand}"/>
</VerticalStackLayout>
</ContentPage>
public partial class LoginPage : ContentPage
{
public LoginPage()
{
InitializeComponent();
this.BindingContext = new LoginViewModel();
}
}
LoginViewModel:
public class LoginViewModel
{
public Command LoginCommand { get; }
public LoginViewModel () { LoginCommand = new Command (OnLoginClicked); }
private async void OnLoginClicked (object obj)
{
// Do some judgment to see if it is compatible with the login
//...
await Shell.Current.GoToAsync ($"//{nameof(MainPage)}");
}
}
Add a button to MainPage for returning to LoginPage:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiApp5.MainPage">
<ScrollView>
<VerticalStackLayout
Spacing="25"
Padding="30,0"
VerticalOptions="Center">
.....
<Button Text="LoginPage" Clicked="Button_Clicked"/>
</VerticalStackLayout>
</ScrollView>
</ContentPage>
public partial class MainPage: ContentPage
{
int count = 0;
public MainPage()
{
InitializeComponent();
}
....
private void Button_Clicked(object sender, EventArgs e)
{
Shell.Current.GoToAsync($"//{nameof(LoginPage)}");
}
}
AppShell.xaml:
<Shell
x:Class="MauiApp5.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MauiApp5"
Shell.FlyoutBehavior="Disabled">
<ShellContent Title="LoginPage" Route="LoginPage" ContentTemplate="{DataTemplate local:LoginPage}" Shell.TabBarIsVisible="False"/>
<FlyoutItem >
<ShellContent Title="Home" Route="MainPage" ContentTemplate="{DataTemplate local:MainPage}" />
<ShellContent Title="NewPage1" Route="NewPage1" ContentTemplate="{DataTemplate local:NewPage1}" />
</FlyoutItem>
</Shell>
Here is the effect.
Upvotes: 0