我在我的应用程序中使用 MVVM,并希望在按下登录按钮后更改 TabBarItems 的可见性。但我不知道最佳实践是什么。
我的 AppShell 中有一个 TabBar,看起来像这样
<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 在开始时不应该是可见的。并且 LoginTab 应该是可见的。我应该从 AppShell 分配代码中的可见性还是有更好的 MVVM 方法?
现在我有了用于登录的 View 和 ViewModel
<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)
{
}
}
}
现在,当我按下登录按钮时,LoginView 不应该可见,而 Tab3 应该可见。希望你能给我一些建议。 谢谢:-)
您可以参考以下代码:
创建 MAUI 项目,然后将 LoginPage 和 NewPage1 添加到根目录,以及 LoginViewModel 中的 ViewModels 文件夹:
登录页面如下:
<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();
}
}
登录视图模型:
public class LoginViewModel
{
public Command LoginCommand { get; }
public LoginViewModel () { LoginCommand = new Command (OnLoginClicked); }
private async void OnLoginClicked (object obj)
{
await Shell.Current.GoToAsync ($"//{nameof(MainPage)}");
}
}
在主页上添加返回登录页面的按钮:
<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)
{
// Do some judgment to see if it is compatible with the login
//...
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>