0

IsVisible有没有动态设置的解决方案ShellItem?我必须解决以下问题:我有一个包含 to 的弹出菜单ShellItem,一个是 Login,另一个是 Logout。

<ShellItem x:Name="LoginItem" Route="login" Title="{resources:Translate Login}" Icon="icon_LogIn.png" >
    <ShellContent ContentTemplate="{DataTemplate views:Account.LoginPage}"/>
</ShellItem>

<ShellItem x:Name="LogoutItem" Route="Logout" Title="{resources:Translate Logout}" Icon="icon_logOut.png" >
    <ShellContent ContentTemplate="{DataTemplate views:Account.SignOutPage}"/>
</ShellItem>

现在不必在弹出菜单中看到它们。如果用户已登录,则只有注销项可见。如果用户没有登录,只有“登录”项应该是可见的。正如我所见,弹出菜单是在应用程序启动时构建的,然后再也不会出现,那么我该如何实现呢?并且没有ShellItem.Behavior等。

ShellItem顺便说一句,和 和有什么区别FlyoutItem

4

2 回答 2

0

在您的 AppShell.xaml.cs 中创建和管理一个属性,该属性反映IsUserAuthenticated要绑定到的经过身份验证的状态IsVisible

InvertedBoolConverter来自Xamarin.CommunityToolkit 包

<Shell.Resource>
   <ResourceDictionary>
       <xct:InvertedBoolConverter x:Key="InvertedBoolConverter" />
   </ResourceDictionary>
</Shell.Resource>


<ShellItem x:Name="LoginItem" Route="login" Title="{resources:Translate Login}" Icon="icon_LogIn.png"
           IsVisible="{Binding IsUserAuthenticated,
                       Converter={StaticResource InvertedBoolConverter}}">
    <ShellContent ContentTemplate="{DataTemplate views:Account.LoginPage}"/>
</ShellItem>

<ShellItem x:Name="LogoutItem" Route="Logout" Title="{resources:Translate Logout}" Icon="icon_logOut.png"
           IsVisible="{Binding IsUserAuthenticated}">
    <ShellContent ContentTemplate="{DataTemplate views:Account.SignOutPage}"/>
</ShellItem>

相关问题

如何根据登录状态/角色限制/控制用户可以访问的导航路线?

于 2021-03-25T12:14:00.187 回答
0

您可以使用 <Shell.FlyoutHeaderTemplate>添加自定义菜单项,然后使用绑定来隐藏/显示菜单。

步骤 1. 实现 InverseBoolConverter 类

namespace MyMobileApp.Converters
{
    public class InverseBoolConverter : Xamarin.Forms.IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return !(bool)value;
        }
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return !(bool)value;
        }
    }
}

第 2 步:在 AppShell.xaml 类中添加 InverseBoolConverter 引用。然后xmlns:converter="clr-namespace:MyMobileApp.Converters"在顶部添加(在 Shell 标记内)。然后<converter:InverseBoolConverter x:Key="cvInverse"></converter:InverseBoolConverter><ResourceDictionary>标签之后添加。

第 3 步:在 AppShell.xaml 中的标记后添加以下代码</FlyoutItem>

<Shell.FlyoutHeaderTemplate>
    <DataTemplate>
        <StackLayout BackgroundColor="White">
            <!--Header-->
            <StackLayout Orientation="Horizontal" BackgroundColor="LightGray" Padding="20" IsVisible="{Binding IsUserLogedin}">
                <Label Text="Watchlist" TextColor="Black" VerticalOptions="CenterAndExpand" HorizontalOptions="StartAndExpand" VerticalTextAlignment="Center">
                    <Label.GestureRecognizers>
                        <TapGestureRecognizer Command="{Binding WatchlistCommand}"/>
                    </Label.GestureRecognizers>
                </Label>
                <Label Text="Logout" TextColor="Black" VerticalOptions="CenterAndExpand" HorizontalOptions="End" VerticalTextAlignment="Center">
                    <Label.GestureRecognizers>
                        <TapGestureRecognizer Command="{Binding LogoutCommand}"/>
                    </Label.GestureRecognizers>
                </Label>
            </StackLayout>
            <StackLayout Orientation="Horizontal" BackgroundColor="LightGray" Padding="20" IsVisible="{Binding IsUserLogedin, Converter={StaticResource cvInverse}}">
                <Label Text="Register" TextColor="Black" VerticalOptions="CenterAndExpand" HorizontalOptions="StartAndExpand" VerticalTextAlignment="Center">
                    <Label.GestureRecognizers>
                        <TapGestureRecognizer Command="{Binding RegisterCommand}"/>
                    </Label.GestureRecognizers>
                </Label>
                <Label Text="Login" TextColor="Black" VerticalOptions="CenterAndExpand" HorizontalOptions="End" VerticalTextAlignment="Center">
                    <Label.GestureRecognizers>
                        <TapGestureRecognizer Command="{Binding LoginCommand}"/>
                    </Label.GestureRecognizers>
                </Label>
            </StackLayout>
        </StackLayout>
    </DataTemplate>
</Shell.FlyoutHeaderTemplate>

步骤 4:在 AppShell.xaml.cs 类中实现绑定

public Xamarin.Forms.Command LoginCommand { get; }
public Xamarin.Forms.Command RegisterCommand { get; }
public Xamarin.Forms.Command LogoutCommand { get; }
public Xamarin.Forms.Command WatchlistCommand { get; }

private bool _isUserLoggedIn;
public bool IsUserLogedin
{
    get => _isUserLoggedIn;
    set => SetProperty(ref _isUserLoggedIn, value);
}
public AppShell()
{   
    InitializeComponent();  
    LoginCommand = new Xamarin.Forms.Command(MenuClicked);
    RegisterCommand = new Xamarin.Forms.Command(MenuClicked);
    LogoutCommand = new Xamarin.Forms.Command(MenuClicked);
    WatchlistCommand = new Xamarin.Forms.Command(MenuClicked);
    BindingContext = this;
}
private async void MenuClicked(object obj)
{
    
}
protected bool SetProperty<T>(ref T backingStore, T value, [System.Runtime.CompilerServices.CallerMemberName] string propertyName = "", System.Action onChanged = null)
        {
            if (System.Collections.Generic.EqualityComparer<T>.Default.Equals(backingStore, value))
                return false;

            backingStore = value;
            onChanged?.Invoke();
            OnPropertyChanged(propertyName);
            return true;
        }
于 2021-07-22T00:45:39.210 回答