如何在Xamarin.Forms中设置顶部与底部工具栏不同颜色
实现Xamarin.Forms上下工具栏不同背景色的方案
这个问题我之前帮朋友解决过,确实Xamarin.Forms默认把上下拆分后的工具栏背景色绑定到同一个BarBackgroundColor属性上,要分开设置得动点小手脚,给你两个可行的方案:
方案一:针对UWP平台自定义NavigationPageRenderer
因为你提到了Windows 10 Mobile,这个方案专门针对UWP平台,直接操作原生控件来分开设置两个工具栏的颜色:
- 在你的UWP项目中创建一个自定义的
NavigationPageRenderer,继承自Xamarin.Forms的默认实现 - 在
OnElementChanged方法中获取UWP原生的Frame控件,找到它的TopAppBar和BottomAppBar(都是CommandBar类型) - 分别给两个
CommandBar设置不同的背景色:顶部用系统强调色,底部用灰色 - 监听
NavigationPage的PropertyChanged事件,防止后续属性变化覆盖你的自定义设置
代码示例
[assembly: ExportRenderer(typeof(NavigationPage), typeof(CustomNavigationPageRenderer))] namespace YourAppNamespace.UWP { public class CustomNavigationPageRenderer : NavigationPageRenderer { protected override void OnElementChanged(ElementChangedEventArgs<NavigationPage> e) { base.OnElementChanged(e); if (Control != null) { UpdateToolbarColors(); Element.PropertyChanged += OnElementPropertyChanged; } } private void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { // 当BarBackgroundColor属性变化时,重新设置工具栏颜色,避免被覆盖 if (e.PropertyName == nameof(NavigationPage.BarBackgroundColor)) { UpdateToolbarColors(); } } private void UpdateToolbarColors() { var uwpFrame = Control as Windows.UI.Xaml.Controls.Frame; if (uwpFrame == null) return; // 设置顶部工具栏为系统强调色 if (uwpFrame.TopAppBar is Windows.UI.Xaml.Controls.CommandBar topBar) { var accentBrush = (Windows.UI.Xaml.Media.SolidColorBrush) Windows.UI.Xaml.Application.Current.Resources["SystemAccentColor"]; topBar.Background = accentBrush; } // 设置底部工具栏为灰色 if (uwpFrame.BottomAppBar is Windows.UI.Xaml.Controls.CommandBar bottomBar) { bottomBar.Background = new Windows.UI.Xaml.Media.SolidColorBrush(Windows.UI.Colors.LightGray); } } } }
这个方案的好处是完全复用系统工具栏的功能(汉堡菜单、命令、弹出菜单),不需要自己重新实现,缺点是只针对UWP平台,如果需要跨平台支持得给其他平台单独写Renderer。
方案二:自定义底部工具栏(跨平台通用)
如果需要跨平台都能用,或者不想写平台特定的Renderer,可以放弃使用系统的底部工具栏,自己在页面底部实现一个自定义工具栏:
- 保持顶部使用默认的
NavigationPage工具栏,设置它的BarBackgroundColor为系统强调色 - 在每个页面的布局中添加一个底部的容器(比如
StackLayout或Grid),设置背景色为灰色,然后在里面添加命令按钮、弹出菜单等控件 - 可以把这个自定义底部工具栏封装成一个可复用的控件,或者创建一个
BasePage让所有页面继承,避免重复代码
代码示例(XAML)
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="YourAppNamespace.MainPage"> <Grid> <!-- 页面内容区域 --> <ScrollView Grid.Row="0"> <!-- 这里放你的页面内容 --> <Label Text="页面内容" VerticalOptions="Center" HorizontalOptions="Center" /> </ScrollView> <!-- 自定义底部工具栏 --> <StackLayout Grid.Row="1" BackgroundColor="LightGray" Orientation="Horizontal" HorizontalOptions="End" Padding="10"> <Button Text="新建" Command="{Binding NewCommand}" /> <Button Text="更多" Command="{Binding MoreCommand}" /> </StackLayout> </Grid> </ContentPage>
这个方案的好处是跨平台通用,完全控制样式,缺点是需要自己实现系统工具栏的部分功能(比如弹出菜单可能需要用Flyout或自定义弹窗),但胜在灵活,所有平台都能保持一致的样式。
额外提示
- 如果你用方案一,记得在UWP项目中启用
NavigationPage的底部工具栏(设置ToolBarPlacement="Bottom") - 方案二中的自定义工具栏可以绑定
Command和CommandParameter,和系统工具栏的用法一致,不影响MVVM架构
内容的提问来源于stack exchange,提问作者LunaticShade
相关产品推荐
相关产品推荐

