分组集合视图在iOS上显示空组

m528fe3b  于 2023-05-19  发布在  iOS
关注(0)|答案(1)|浏览(154)

我有一个MAUI应用程序,其中一个视图绑定到一个包含分组CollectionView的视图模型,并设置了以下属性:

<CollectionView
           x:Name="MyList"
           VerticalOptions="FillAndExpand"
           ItemsSource="{Binding CollectionViewItemSourceGrouped}"
           SelectionMode="Single"                   
           SelectedItem="{Binding MyItem, Mode=TwoWay}"
           SelectionChangedCommand="{Binding MySelectionCommand}"
           RemainingItemsThreshold="2"
           RemainingItemsThresholdReachedCommand="{Binding LoadMoreItemsCommand}"
           IsGrouped="True"
           EmptyView="No item found.">

我从一个可等待的Web API获取并分组源项,当我第一次导航到视图中时,如果我开始来回切换筛选列表的开关,我就正确地将集合分组。不幸的是,当我导航到一个详细信息页面,然后通过Shell导航返回到集合时,如果我再次操作开关并重新加载列表,我总是会得到一些空组,这在图形上会导致一个大混乱。用作集合源的对象是CollectionViewItemSourceGrouped,它是一个ObservableCollection<ItemsGroup>,具有以下实现:

public class ItemsGroup : ObservableRangeCollection<ItemModel>
{
    public DateTime Date { get; private set; }

    public ItemsGroup(DateTime date, ObservableRangeCollection<ItemModel> list) : base(list)
    {
        Date = date;
    }
}

下面是数据的加载方式:

try
        {
            if (InLoading)
                return;

            InLoading = true;

            //Selectio item gets blanked
            if (MyItem is not null)
                MyItem = null;

            CollectionViewItemSourceGrouped = new();

            paginationIndex = 1;

            IEnumerable<ItemsGroup> grpItems = await LoadItemsSub(0, MaxItemsPerPage);

            if (grpItems != null && grpItems.Any())
                CollectionViewItemSourceGrouped = new ObservableRangeCollection<ItemsGroup>(grpItems.OrderByDescending(s => s.Date));
            else           
                CollectionViewItemSourceGrouped = new();
        }
        catch (LocalException ex)
        {
            UIMessagesManager.ShowMessage(Stringhe.DANGER, ex.Message);
        }
        catch (Exception ex)
        {
            AppCenterEventManager.TrackError(ex, string.Empty);

            UIMessagesManager.ShowMessage(Stringhe.DANGER, Stringhe.UNKNOWN_ERROR);
        }
        finally
        {
            InLoading = false;
        }

每次重载数据时,我都要确保对象CollectionViewItemSourceGrouped被设置为null或者是一个新的空对象。我希望集合是空的,而不是继续显示只有头集的空组。我怎样才能摆脱它们,让集合正确刷新?

这仅适用于iOS和MacCatalyst。它可以在Android和WinUI上运行。

在上图中,标题01/05/2023是意外的,显示为空组。但是项源已经在视图模型中正确地重新分配。这是我的期望:

我尝试了几乎所有的东西,但在iOS和MacCatalyst上没有运气。

更新1

这是一个GitHub公共存储库和一个示例项目。尝试在iOS模拟器上执行它,当VerticalOptions=FillAndExpandCollectionView时,您将能够看到这种奇怪的行为。[见图]

GitHub Repository - GroupedCollectionSample

更新2

请注意,如果我为容器(StackLayout)设置VerticalOptions,我将继续获得相同的“空”组头奇怪行为。我目前“解决”离开StackLayout和设置一个固定的HeightRequestCollectionView,但当然它不适合所有设备。
我还尝试将其设置为Grid,这是代码。这并不能解决任何问题,因为集合一直在屏幕外扩展,所以滚动到底部变得不可能(我认为这是因为容器没有固定的结束)。我不知道该怎么办,因为:改变容器VerticalOptions导致问题,将其保留在默认值会导致CollectionView不滚动到底部。

<StackLayout>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Heigth="40" />
            <RowDefinition Heigth="*" />  
        </Grid.RowDefinitions>
        
        <StackLayout
            Grid.Row = "0"
            HeightRequest="40"
            Orientation="Horizontal">
            
            <Switch
                VerticalOptions="Center"
                Margin="10,0"
                IsToggled="{Binding FilterData}">
                <Switch.Behaviors>
                    <toolkit:EventToCommandBehavior
                        EventName="Toggled"
                        Command="{Binding FilterDataCommand}" />
                </Switch.Behaviors>
            </Switch>

            <Label 
                Text="Only enabled users"/>
        </StackLayout>

        <CollectionView
            x:Name="ListUsers"
            Grid.Row = "1"
            VerticalOptions="FillAndExpand"
            ItemsSource="{Binding ListUsersGroup}"
            SelectionMode="Single"                   
            SelectedItem="{Binding CurrentUser, Mode=TwoWay}"
            SelectionChangedCommand="{Binding OpenDetailCommand}"
            IsGrouped="True"
            EmptyView="No user found.">

            <CollectionView.GroupHeaderTemplate>
                <DataTemplate x:DataType="extModels:UsersGroup">
                    <Label
                        Padding="10,8"
                        BackgroundColor="Gray"
                        TextColor="Black"
                        Text="{Binding Date}"
                        FontAttributes="Bold"
                        FontSize="15"/>
                </DataTemplate>
            </CollectionView.GroupHeaderTemplate>

            <CollectionView.ItemTemplate>
                <DataTemplate x:DataType="extModels:User">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="auto" />
                            <ColumnDefinition Width="auto" />
                        </Grid.ColumnDefinitions>

                        <Grid.RowDefinitions>
                            <RowDefinition Height="50"/>
                        </Grid.RowDefinitions>
                        <Label
                            Grid.Column="0"
                            Margin="20,0"
                            Text="{Binding FirstName}">
                        </Label>

                        <Label 
                            Grid.Column="1"
                            Text="{Binding LastName}" >
                        </Label>
                    </Grid>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </Grid>
</StackLayout>
baubqpgj

baubqpgj1#

我没有时间回顾所有的事情,但这里:

<StackLayout>
        <StackLayout
            HeightRequest="40"
            Orientation="Horizontal">
            
            <Switch
                VerticalOptions="Center"
                Margin="10,0"
                IsToggled="{Binding FilterData}">
                <Switch.Behaviors>
                    <toolkit:EventToCommandBehavior
                        EventName="Toggled"
                        Command="{Binding FilterDataCommand}" />
                </Switch.Behaviors>
            </Switch>

            <Label 
                Text="Only enabled users"/>
        </StackLayout>

        <CollectionView
            x:Name="ListUsers"
            VerticalOptions="FillAndExpand"
            ItemsSource="{Binding ListUsersGroup}"
            SelectionMode="Single"                   
            SelectedItem="{Binding CurrentUser, Mode=TwoWay}"
            SelectionChangedCommand="{Binding OpenDetailCommand}"
            IsGrouped="True"
            EmptyView="No user found.">

这已经足够了。。你在“填”什么?你要怎么填东西,没有底的?
而且,您现在看到了,“提供更多代码”是多么有意义。在你最初的问题中,因为我没有看到家长,所以我没有注意到这一点。
编辑:限制容器中物品的高度是一种方法。现在,通常您会希望限制容器本身。
在您的场景中,A GridRowDefinitions= "40,*"将给予所需的结果。(第一行40,第二行,尽可能多)。这样,您可以将StackLayout放在Row = 0中,将CollectionView放在Row = 1中,并让它们占用所有空间。
(So这样,您的设计将在不同的电话屏幕上工作。)
编辑2:

<StackLayout> <<< This here has no height restriction. Delete this.
<Grid> <<< This will match your view. Keep it.
    <Grid.RowDefinitions>
        <RowDefinition Heigth="40" />
        <RowDefinition Heigth="*" />  <<< this here reads "fill"
    </Grid.RowDefinitions>
    
    <StackLayout
        Grid.Row = "0"
        HeightRequest="40"
        Orientation="Horizontal">
        
        <Switch
            VerticalOptions="Center"
            Margin="10,0"
            IsToggled="{Binding FilterData}">
            <Switch.Behaviors>
                <toolkit:EventToCommandBehavior
                    EventName="Toggled"
                    Command="{Binding FilterDataCommand}" />
            </Switch.Behaviors>
        </Switch>

        <Label 
            Text="Only enabled users"/>
    </StackLayout>

    <CollectionView

相关问题