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

Xamarin Forms中ListView内容不显示及组头文字颜色异常问题

按周分组列表的两个问题排查与修复

我需要实现按周划分的列表,每个周分组(对应GroupedWeeksModel类)包含多个Event和Recovery条目,但目前遇到两个问题:

  • ListView.ItemTemplate中的内容完全无法显示
  • ListView.GroupHeaderTemplate里的文字颜色显示异常

相关代码

EventsPage.xaml

<ScrollView>
    <StackLayout Orientation="Vertical">
        <ListView BackgroundColor="DeepPink" IsGroupingEnabled="True" ItemsSource="{Binding GroupedWeeks}" GroupDisplayBinding="{Binding DateString}" SeparatorVisibility="None" VerticalOptions="Start" x:Name="weeksList" HasUnevenRows="True">
            <ListView.GroupHeaderTemplate>
                <DataTemplate>
                    <ViewCell Height="60">
                        <StackLayout VerticalOptions="Center">
                            <Label Text="{Binding DateString}" TextColor="White" VerticalOptions="Center"/>
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.GroupHeaderTemplate>
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell Height="75">
                        <StackLayout HeightRequest="200" WidthRequest="200">
                                    
                            <Label> Why isn't this text appearing? </Label>

                            <StackLayout BindableLayout.ItemsSource="{Binding Events}">
                                <BindableLayout.ItemTemplate>
                                    <DataTemplate>
                                        <ui:MaterialCard HeightRequest="70" Margin="20, 0, 20, 5" Padding="0" BackgroundColor="Red">
                                            <StackLayout Padding="10, 0, 0, 0" HorizontalOptions="StartAndExpand" Orientation="Horizontal">
                                                <StackLayout Orientation="Vertical" WidthRequest="30" VerticalOptions="Center" HorizontalOptions="Center">
                                                    <ui:MaterialLabel TextColor="White" Text="{Binding ShortMonth}"/>
                                                    <ui:MaterialLabel FontSize="Large" TextColor="White" Text="{Binding Day}"/>
                                                </StackLayout>
                                                <StackLayout Orientation="Vertical" VerticalOptions="Center" HorizontalOptions="StartAndExpand">
                                                    <ui:MaterialLabel LineBreakMode="TailTruncation" TextColor="White" Text="{Binding Name}"/>
                                                    <ui:MaterialLabel TextColor="White" Text="{Binding FullDate}"/>
                                                </StackLayout>
                                            </StackLayout>
                                        </ui:MaterialCard>
                                    </DataTemplate>
                                </BindableLayout.ItemTemplate>
                            </StackLayout>

                            <StackLayout BindableLayout.ItemsSource="{Binding Recoveries}">
                                <BindableLayout.ItemTemplate>
                                    <DataTemplate>
                                        <ui:MaterialCard HeightRequest="70" Margin="20, 0, 20, 5" Padding="0" BackgroundColor="Green">
                                            <StackLayout Padding="10, 0, 0, 0" HorizontalOptions="StartAndExpand" Orientation="Horizontal">
                                                <StackLayout Orientation="Vertical" WidthRequest="30" VerticalOptions="Center" HorizontalOptions="Center">
                                                    <ui:MaterialLabel TextColor="White" Text="{Binding ShortMonth}"/>
                                                    <ui:MaterialLabel FontSize="Large" TextColor="White" Text="{Binding Day}"/>
                                                </StackLayout>
                                                <StackLayout Orientation="Vertical" VerticalOptions="Center" HorizontalOptions="StartAndExpand">
                                                    <ui:MaterialLabel LineBreakMode="TailTruncation" TextColor="White" Text="{Binding RecoveryType.Name}"/>
                                                    <ui:MaterialLabel TextColor="White" Text="{Binding Date}"/>
                                                </StackLayout>
                                            </StackLayout>
                                        </ui:MaterialCard>
                                    </DataTemplate>
                                </BindableLayout.ItemTemplate>
                            </StackLayout>
                        </StackLayout>
                    </ViewCell> 
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ScrollView>

EventsPage.xaml.cs

public partial class EventsPage : ContentPage
{
    public EventsPage()
    {
        InitializeComponent();
        BindingContext = new EventsViewModel();
    }
}

EventsViewModel及GroupedWeeksModel

public class EventsViewModel : BaseViewModel
{
    public ObservableCollection<GroupedWeeksModel> GroupedWeeks { get; set; } = new ObservableCollection<GroupedWeeksModel>();

    public EventsViewModel()
    {
        Device.BeginInvokeOnMainThread(async () => await InitializeAsync());
    }

    public async Task InitializeAsync()
    {
        GroupedWeeks = await LoadEventsAndRecoveries();
    }
}

public class GroupedWeeksModel
{
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
    public string DateString => // 自定义日期格式化逻辑
    public ObservableCollection<EventResponse> Events { get; set; } = new ObservableCollection<EventResponse>();
    public ObservableCollection<RecoveryResponse> Recoveries { get; set; } = new ObservableCollection<RecoveryResponse>();
}

问题修复方案

1. ItemTemplate内容不显示的修复

核心原因

  • 分组ListView的数据源结构错误:Xamarin.Forms要求分组集合的每个组必须包含单个子项集合,而当前GroupedWeeksModel拆分了Events和Recoveries两个集合,ListView无法识别为组内条目
  • ViewCell固定高度(75)与内部布局高度(200)冲突,内容被强制截断
  • 嵌套ScrollView与ListView自带滚动冲突,导致布局计算异常

修复步骤

(1)重构数据模型,统一组内子项

创建基类统一Event和Recovery的展示字段,让分组模型继承可观察集合:

public class BaseEntry
{
    public string ShortMonth { get; set; }
    public string Day { get; set; }
    public string Title { get; set; }
    public string Subtitle { get; set; }
    public bool IsRecovery { get; set; }
}

public class EventResponse : BaseEntry { }
public class RecoveryResponse : BaseEntry { }

public class GroupedWeeksModel : ObservableCollection<BaseEntry>
{
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
    public string DateString => $"{StartDate:MM/dd} - {EndDate:MM/dd}";

    public ObservableCollection<EventResponse> Events { get; set; } = new ObservableCollection<EventResponse>();
    public ObservableCollection<RecoveryResponse> Recoveries { get; set; } = new ObservableCollection<RecoveryResponse>();

    public GroupedWeeksModel()
    {
        Events.CollectionChanged += (s, e) => SyncEntries();
        Recoveries.CollectionChanged += (s, e) => SyncEntries();
    }

    private void SyncEntries()
    {
        Clear();
        foreach (var ev in Events)
        {
            ev.Title = ev.Name;
            ev.Subtitle = ev.FullDate;
            ev.IsRecovery = false;
            Add(ev);
        }
        foreach (var rec in Recoveries)
        {
            ev.Title = rec.RecoveryType.Name;
            ev.Subtitle = rec.Date.ToString();
            ev.IsRecovery = true;
            Add(rec);
        }
    }
}
(2)修改ListView布局,移除冲突设置

去掉外层ScrollView,修改ItemTemplate直接渲染统一子项:

<StackLayout Orientation="Vertical">
    <ListView BackgroundColor="DeepPink" IsGroupingEnabled="True" ItemsSource="{Binding GroupedWeeks}" 
              SeparatorVisibility="None" x:Name="weeksList" HasUnevenRows="True">
        <!-- 组头模板 -->
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell HasUnevenRows="True">
                    <ui:MaterialCard HeightRequest="70" Margin="20, 0, 20, 5" Padding="0"
                                     BackgroundColor="{Binding IsRecovery, Converter={StaticResource BoolToColorConverter}, ConverterParameter='Green,Red'}">
                        <StackLayout Padding="10, 0, 0, 0" HorizontalOptions="StartAndExpand" Orientation="Horizontal">
                            <StackLayout Orientation="Vertical" WidthRequest="30" VerticalOptions="Center" HorizontalOptions="Center">
                                <ui:MaterialLabel TextColor="White" Text="{Binding ShortMonth}"/>
                                <ui:MaterialLabel FontSize="Large" TextColor="White" Text="{Binding Day}"/>
                            </StackLayout>
                            <StackLayout Orientation="Vertical" VerticalOptions="Center" HorizontalOptions="StartAndExpand">
                                <ui:MaterialLabel LineBreakMode="TailTruncation" TextColor="White" Text="{Binding Title}"/>
                                <ui:MaterialLabel TextColor="White" Text="{Binding Subtitle}"/>
                            </StackLayout>
                        </StackLayout>
                    </ui:MaterialCard>
                </ViewCell> 
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</StackLayout>
(3)修复ViewModel属性通知

确保GroupedWeeks属性变更时能通知UI更新:

public class EventsViewModel : BaseViewModel
{
    private ObservableCollection<GroupedWeeksModel> _groupedWeeks;
    public ObservableCollection<GroupedWeeksModel> GroupedWeeks 
    { 
        get => _groupedWeeks; 
        set => SetProperty(ref _groupedWeeks, value);
    }

    public EventsViewModel()
    {
        _groupedWeeks = new ObservableCollection<GroupedWeeksModel>();
        Device.BeginInvokeOnMainThread(async () => await InitializeAsync());
    }

    public async Task InitializeAsync()
    {
        var data = await LoadEventsAndRecoveries();
        GroupedWeeks = data;
    }
}

2. GroupHeaderTemplate文字颜色异常的修复

核心原因

组头模板错误使用ViewCell,导致系统默认样式覆盖自定义文字颜色;同时GroupDisplayBinding与模板内绑定重复引发冲突。

修复步骤

修改组头模板,移除ViewCell:

<ListView.GroupHeaderTemplate>
    <DataTemplate>
        <StackLayout VerticalOptions="Center" HeightRequest="60" BackgroundColor="DeepPink">
            <Label Text="{Binding DateString}" TextColor="White" VerticalOptions="Center" 
                   HorizontalOptions="Start" Margin="20,0,0,0"/>
        </StackLayout>
    </DataTemplate>
</ListView.GroupHeaderTemplate>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 04:59:51