You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Xamarin主菜单的菜单项组之间绘制水平线?

嘿,我之前刚好解决过这个需求——要在Xamarin Forms的菜单里只在特定两组菜单项之间加水平线,而不是每个项都显示默认分隔线。给你一套可行的方案,完全自定义控制分隔线的位置和样式:

1. 定义菜单项类型和数据模型

首先我们需要区分普通菜单项和分隔线项,所以先建一个枚举和对应的数据模型:

namespace GMG
{
    public enum MenuItemType
    {
        Normal, // 普通菜单项
        Separator // 分隔线项
    }

    public class MasterPageItem
    {
        public MenuItemType Type { get; set; }
        public string Title { get; set; }
        public string IconSource { get; set; }
        public Type TargetType { get; set; } // 跳转页面类型,可根据你的需求调整
    }
}

2. 创建自定义分隔线Cell

接下来做一个专门用来显示水平线的ViewCell,你可以自定义它的颜色、高度和边距:

namespace GMG
{
    public class HorizontalLineCell : ViewCell
    {
        public HorizontalLineCell()
        {
            var line = new BoxView
            {
                HeightRequest = 1, // 分隔线高度
                BackgroundColor = Color.DarkGray, // 分隔线颜色
                Margin = new Thickness(20, 0) // 左右缩进,让线条不贴边
            };

            View = new StackLayout
            {
                Children = { line },
                Padding = new Thickness(0, 8, 0, 8) // 上下留白,避免和菜单项太挤
            };
        }
    }
}

3. 实现模板选择器

我们需要一个模板选择器,让ListView根据菜单项的类型,自动选择显示普通项还是分隔线:

namespace GMG
{
    public class MenuItemTemplateSelector : DataTemplateSelector
    {
        public DataTemplate NormalItemTemplate { get; set; }
        public DataTemplate SeparatorTemplate { get; set; }

        protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
        {
            var masterItem = item as MasterPageItem;
            return masterItem?.Type == MenuItemType.Separator ? SeparatorTemplate : NormalItemTemplate;
        }
    }
}

4. 在XAML中配置ListView

打开你的MasterDetailPage1Master.xaml,配置资源字典和ListView的模板,记得关闭默认的分隔线:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:GMG"
             x:Class="GMG.MasterDetailPage1Master">
    <ContentPage.Resources>
        <ResourceDictionary>
            <!-- 普通菜单项模板 -->
            <DataTemplate x:Key="NormalItemTemplate">
                <ViewCell>
                    <StackLayout Orientation="Horizontal" Padding="15,12">
                        <Image Source="{Binding IconSource}" WidthRequest="22" HeightRequest="22" Margin="0,0,12,0"/>
                        <Label Text="{Binding Title}" FontSize="16" VerticalOptions="Center"/>
                    </StackLayout>
                </ViewCell>
            </DataTemplate>

            <!-- 分隔线模板 -->
            <DataTemplate x:Key="SeparatorTemplate">
                <local:HorizontalLineCell/>
            </DataTemplate>

            <!-- 绑定模板选择器 -->
            <local:MenuItemTemplateSelector x:Key="MenuItemSelector"
                                            NormalItemTemplate="{StaticResource NormalItemTemplate}"
                                            SeparatorTemplate="{StaticResource SeparatorTemplate}"/>
        </ResourceDictionary>
    </ContentPage.Resources>

    <!-- 配置ListView,关闭默认分隔线 -->
    <ListView x:Name="ListView"
              ItemTemplate="{StaticResource MenuItemSelector}"
              SeparatorVisibility="None"
              HasUnevenRows="True">
    </ListView>
</ContentPage>

5. 初始化菜单数据,插入分隔线

最后回到C#代码,在构造函数里创建菜单数据,在需要分隔的位置插入Separator类型的项:

using System.Collections.Generic;
using Xamarin.Forms;

namespace GMG
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class MasterDetailPage1Master : ContentPage
    {
        public ListView ListView;

        public MasterDetailPage1Master()
        {
            InitializeComponent();
            ListView = this.ListView;

            // 构建菜单数据,在两组之间插入分隔线
            var menuItems = new List<MasterPageItem>
            {
                new MasterPageItem { Type = MenuItemType.Normal, Title = "首页", IconSource = "home.png", TargetType = typeof(HomePage) },
                new MasterPageItem { Type = MenuItemType.Normal, Title = "个人中心", IconSource = "profile.png", TargetType = typeof(ProfilePage) },
                // 这里就是我们要的分隔线,插在两组之间
                new MasterPageItem { Type = MenuItemType.Separator },
                new MasterPageItem { Type = MenuItemType.Normal, Title = "设置", IconSource = "settings.png", TargetType = typeof(SettingsPage) },
                new MasterPageItem { Type = MenuItemType.Normal, Title = "关于我们", IconSource = "about.png", TargetType = typeof(AboutPage) }
            };

            ListView.ItemsSource = menuItems;
        }
    }
}

这样一来,你就可以精准控制水平线出现的位置了——想在哪两组之间加,就插入一个MenuItemType.Separator的项就行。如果要调整分隔线的样式,直接修改HorizontalLineCell里的BoxView属性就好,非常灵活。

内容的提问来源于stack exchange,提问作者Tariq Khalifa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:26:51