如何在MAUI中实现类似Xamarin.Forms的TabView功能?
替代MAUI中Uranium TabView的实现方案
以下是几种能复刻你Xamarin.Forms中TabView效果的实现方式:
方法1:自定义TabView(完全匹配原有需求)
这种方式可以1:1还原你之前的样式和功能,通过CollectionView做标签栏,配合ContentView切换内容,灵活性拉满。
XAML代码
<Grid> <!-- 标签栏 --> <CollectionView x:Name="TabHeader" HeightRequest="60" BackgroundColor="{StaticResource Background}" ItemsSource="{Binding TabItems}" SelectedItem="{Binding SelectedTab}" HorizontalScrollBarVisibility="Never" ItemsLayout="HorizontalList"> <CollectionView.ItemTemplate> <DataTemplate> <Grid WidthRequest="240" Padding="10" HorizontalOptions="Center"> <!-- 标签文本 --> <Label Text="{Binding Title}" FontFamily="{Binding IsSelected, Converter={StaticResource BoolToFontFamilyConverter}, ConverterParameter='Roboto,RobotoBold'}" FontSize="{markupExtensions:OnScreenSize DefaultSize='20', Low='13', Medium='14', High='16', XHigh='18', XXHigh='20', XXXHigh='22'}" TextColor="{StaticResource GrayWhite}" FontAttributes="{Binding IsSelected, Converter={StaticResource BoolToFontAttributesConverter}}" HorizontalOptions="Center" VerticalOptions="Center"/> <!-- 选中指示器 --> <BoxView HeightRequest="6" BackgroundColor="White" IsVisible="{Binding IsSelected}" VerticalOptions="End" HorizontalOptions="Fill"/> </Grid> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView> <!-- 内容切换区域 --> <ContentView Margin="0,60,0,0" Content="{Binding SelectedTab.Content}"/> </Grid>
后端逻辑
先定义TabItem模型:
public class TabItem : ObservableObject { private bool _isSelected; public string Title { get; set; } public View Content { get; set; } public bool IsSelected { get => _isSelected; set => SetProperty(ref _isSelected, value); } }
再在ViewModel中初始化数据:
public ObservableCollection<TabItem> TabItems { get; set; } private TabItem _selectedTab; public TabItem SelectedTab { get => _selectedTab; set { if (_selectedTab != null) _selectedTab.IsSelected = false; SetProperty(ref _selectedTab, value); if (_selectedTab != null) _selectedTab.IsSelected = true; } } // 初始化标签和内容 public YourViewModel() { TabItems = new ObservableCollection<TabItem> { new TabItem { Title = "Search Order", Content = new SearchOrderView(), IsSelected = true }, new TabItem { Title = "Scan Order", Content = new ScanOrderView() } }; SelectedTab = TabItems[0]; }
最后添加两个转换器(在Resources中注册):
// 布尔值转字体家族 public class BoolToFontFamilyConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { var fonts = parameter.ToString().Split(','); return (bool)value ? fonts[1] : fonts[0]; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException(); } // 布尔值转字体属性 public class BoolToFontAttributesConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return (bool)value ? FontAttributes.Bold : FontAttributes.None; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException(); }
方法2:使用MAUI Community Toolkit的TabView
MAUI社区工具包的TabView和你之前用的Xamarin XCT TabViewAPI高度一致,几乎可以直接复用原有代码。
- 安装NuGet包:
CommunityToolkit.Maui - 在
MauiProgram.cs中注册:
builder.UseMauiApp<App>().UseMauiCommunityToolkit();
- 编写XAML代码:
<Grid> <mct:TabView TabStripPlacement="Top" TabStripBackgroundColor="{StaticResource Background}" TabStripHeight="60" TabIndicatorHeight="6" TabIndicatorColor="White" IsClippedToBounds="False" TabContentBackgroundColor="White"> <mct:TabViewItem TabWidth="240" Text="Search Order" FontFamily="Roboto" FontFamilySelected="RobotoBold" TextColor="{StaticResource GrayWhite}" TextColorSelected="{StaticResource GrayWhite}" FontAttributesSelected="Bold" FontSizeSelected="{markupExtensions:OnScreenSize DefaultSize='20', Low='13', Medium='14', High='16', XHigh='18', XXHigh='20', XXXHigh='22'}" FontSize="{markupExtensions:OnScreenSize DefaultSize='20', Low='13', Medium='14', High='16', XHigh='18', XXHigh='20', XXXHigh='22'}"> <Grid HorizontalOptions="FillAndExpand" BackgroundColor="{StaticResource Background}" ColumnDefinitions="*"> <innerviews:SearchOrderView x:Name="searchOrderView" Grid.Column="0"> </innerviews:SearchOrderView> </Grid> </mct:TabViewItem> <mct:TabViewItem TabWidth="240" Text="Scan Order" FontFamily="Roboto" FontFamilySelected="RobotoBold" TextColor="{StaticResource GrayWhite}" TextColorSelected="{StaticResource GrayWhite}" FontAttributesSelected="Bold" FontSizeSelected="{markupExtensions:OnScreenSize DefaultSize='20', Low='13', Medium='14', High='16', XHigh='18', XXHigh='20', XXXHigh='22'}" FontSize="{markupExtensions:OnScreenSize DefaultSize='20', Low='13', Medium='14', High='16', XHigh='18', XXHigh='20', XXXHigh='22'}"> <Grid BackgroundColor="{StaticResource Background}" ColumnDefinitions="25*, 50*, 25*" RowDefinitions="15*, 70*, 15*"> <innerviews:ScanOrderView x:Name="scanOrderView" Grid.Column="1" Grid.Row="1"> </innerviews:ScanOrderView> </Grid> </mct:TabViewItem> </mct:TabView> </Grid>
内容的提问来源于stack exchange,提问作者Kavindu Mihiran
相关产品推荐
相关产品推荐

