我有一个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=FillAndExpand
为CollectionView
时,您将能够看到这种奇怪的行为。[见图]
GitHub Repository - GroupedCollectionSample
更新2
请注意,如果我为容器(StackLayout
)设置VerticalOptions
,我将继续获得相同的“空”组头奇怪行为。我目前“解决”离开StackLayout
和设置一个固定的HeightRequest
到CollectionView
,但当然它不适合所有设备。
我还尝试将其设置为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>
1条答案
按热度按时间baubqpgj1#
我没有时间回顾所有的事情,但这里:
这已经足够了。。你在“填”什么?你要怎么填东西,没有底的?
而且,您现在看到了,“提供更多代码”是多么有意义。在你最初的问题中,因为我没有看到家长,所以我没有注意到这一点。
编辑:限制容器中物品的高度是一种方法。现在,通常您会希望限制容器本身。
在您的场景中,A
Grid
和RowDefinitions= "40,*"
将给予所需的结果。(第一行40,第二行,尽可能多)。这样,您可以将StackLayout
放在Row = 0
中,将CollectionView
放在Row = 1
中,并让它们占用所有空间。(So这样,您的设计将在不同的电话屏幕上工作。)
编辑2: