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
2条答案
按热度按时间x9ybnkn61#
它不起作用的原因是,您更新的不是属性,而是字段,这导致从未调用OnPropertyChanged,因此您的UI从未更新。
祝你好运!
cwxwcias2#
我只是想告诉大家,我刚刚解决了这个问题。
1.我完全删除了AppShellViewModel.cs,并将其内容放在AppShell.xaml.cs中(后面的代码)
1.而不是使用MessagingCenter,我只是使用了以下代码(代码包含在登录函数中)
但是,我仍然在寻找其他的解决方案,这样我就可以分离AppShell视图和它的视图模型。所以如果你有其他的解决方案,请在这里发布^_^。谢谢