Xamarin基于值隐藏和显示弹出项目

uz75evzq  于 2022-12-07  发布在  其他
关注(0)|答案(2)|浏览(135)

I am currently learning xamarin forms bits by bits when I had this problem. I wanna make an app where a certain flyout item will be hidden if the user is not an admin. However, even after a successful login of an admin, the flyout item stays hidden. Here's the simplified version of the app.
Here's my code for AppShell.xaml:

<Shell.BindingContext>
     <viewmodel:AppShellViewModel></viewmodel:AppShellViewModel>
 </Shell.BindingContext>
 <ShellItem Route="LoginPage" FlyoutItemIsVisible="False">
     <ShellContent ContentTemplate="{DataTemplate view:LoginPage}"/>
 </ShellItem>
 <FlyoutItem Title="Page 1">
     <ShellContent Route="Page" ContentTemplate="{DataTemplate view:Page}"/>
 </FlyoutItem>
 <FlyoutItem Title="Page 2" IsVisible="{Binding isAdmin}">
     <ShellContent Route="Page2" ContentTemplate="{DataTemplate view:Page2}"/>
 </FlyoutItem>
 <MenuItem Text="isAdmin?" Command="{Binding checkCommand}"/>

AppShellViewModel.cs:

public class AppShellViewModel: BindableObject
 {
     public AppShellViewModel()
     {
         MessagingCenter.Subscribe<LoginViewModel>(this, message: "user", (sender) => {
             _isAdmin = false;
         });
         MessagingCenter.Subscribe<LoginViewModel>(this, message: "admin", (sender) => {
             _isAdmin = true;
         });
         checkCommand = new Command(async () => await checkAdmin());
     }
     private bool _isAdmin;
     public bool isAdmin
     {
         get { return _isAdmin; }
         set
         {
             _isAdmin = value;
             OnPropertyChanged();
         }
     }
     public ICommand checkCommand { get; }
     private async Task checkAdmin()
     {
         string str = $"isAdmin: {_isAdmin}";
         await App.Current.MainPage.DisplayAlert("Alert", str, "OK");
     }
 }

As I've said, the isAdmin will be modified through login method. if the user enter 'admin', isAdmin will be set to true and if it's 'user', false.
Here's my LoginPage.xaml:

<ContentPage.BindingContext>
     <viewmodel:LoginViewModel></viewmodel:LoginViewModel>
 </ContentPage.BindingContext>
 <ContentPage.Content>
     <StackLayout>
         <Entry Text="{Binding user}"/>
         <Button Text="Login" Command="{Binding loginCommand}"/>
     </StackLayout>
 </ContentPage.Content>

Here's my LoginViewModel.cs :

public class LoginViewModel: BindableObject
 {
     public LoginViewModel()
     {
         loginCommand = new Command(async () => await LoginFunc());
     }
     public ICommand loginCommand { get; }
     string _user;
     public string user
     {
         get => _user;
         set
         {
             _user = value;
             OnPropertyChanged();
         }
     }
    
     private async Task LoginFunc()
     {
         if(_user != null)
         {
             MessagingCenter.Send<LoginViewModel>(this, _user);
             await Shell.Current.GoToAsync($"//{nameof(Page)}");
         }
     }
 }

As per code above, I manage (correct me if my method is wrong) to modify the isAdmin by using MessagingCenter , which can be shown if I click the "isAdmin?" MenuItem.
I don't know if the isVisible is working even after the isAdmin property is change (when i tried to initialize isAdmin = true , the flyout item keeps showing even if the user is not an admin).
I would be grateful for any help/tips I will receive. Thank you in advance

x9ybnkn6

x9ybnkn61#

它不起作用的原因是,您更新的不是属性,而是字段,这导致从未调用OnPropertyChanged,因此您的UI从未更新。

public AppShellViewModel()
 {
     MessagingCenter.Subscribe<LoginViewModel>(this, message: "user", (sender) => {
         isAdmin = false;
     });
     MessagingCenter.Subscribe<LoginViewModel>(this, message: "admin", (sender) => {
         isAdmin = true;
     });
     checkCommand = new Command(async () => await checkAdmin());
 }

祝你好运!

cwxwcias

cwxwcias2#

我只是想告诉大家,我刚刚解决了这个问题。
1.我完全删除了AppShellViewModel.cs,并将其内容放在AppShell.xaml.cs中(后面的代码)
1.而不是使用MessagingCenter,我只是使用了以下代码(代码包含在登录函数中)

if(_user == "admin")
{
(Shell.Current as AppShell).isAdmin = true;
}
else
{
(Shell.Current as AppShell).isAdmin = false;
}

但是,我仍然在寻找其他的解决方案,这样我就可以分离AppShell视图和它的视图模型。所以如果你有其他的解决方案,请在这里发布^_^。谢谢

相关问题