Windows平台CommunityToolkit.Maui Popup中CollectionView自动缩放问题
CommunityToolkit.Maui Popup中CollectionView Windows平台自动高度失效问题
问题描述
我正在为CommunityToolkit.Maui的toolkit:Popup中的CollectionView实现自动高度调整。Popup内包含标题、输入框和触发填充CollectionView的按钮,但Popup或CollectionView的高度无法自动扩展,导致搜索结果无法正常显示:
- Android平台运行正常
- Windows平台仅在热重载修改
HeightRequest/MinimumHeightRequest时临时生效,重新调试后失效 - 已尝试修改
HorizontalOptions、VerticalOptions、最小/最大宽高,甚至将VerticalStackLayout替换为Grid,问题仍未解决
代码示例
<?xml version="1.0" encoding="utf-8" ?> <toolkit:Popup xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="SimpleRunManager.Views.Popups.SetStaticLocalizationPopup" xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit" xmlns:viewmodel="clr-namespace:SimpleRunManager.ViewModels" x:DataType="viewmodel:SetStaticLocalizationPopupViewModel" xmlns:model="clr-namespace:SimpleRunManager.Models" Color="{StaticResource MainPopup}" CanBeDismissedByTappingOutsideOfPopup="True" HorizontalOptions="{OnPlatform Default='Fill', WinUI='Center'}" VerticalOptions="Center"> <!-- TODO -> style --> <VerticalStackLayout MinimumWidthRequest="{OnPlatform WinUI='500'}" BackgroundColor="{StaticResource MainPopup}" MaximumHeightRequest="{OnPlatform WinUI='601'}" VerticalOptions="FillAndExpand"> <Grid ColumnDefinitions="{OnPlatform Default='*,auto', WinUI='*,*'}"> <Label Grid.ColumnSpan="{OnPlatform Default='1', WinUI='2'}" Text="Set localization" VerticalOptions="Center" HorizontalOptions="CenterAndExpand" Style="{StaticResource HeaderLabel}" FontAttributes="Bold" Padding="10,20,10,20"/> <Button Grid.Column="1" Text="Delete" Style="{StaticResource DangerButton}" HorizontalOptions="End" Margin="0,20,15,20" Command="{Binding DeleteStaticLocalizationCommand}" CommandParameter="{Binding Source={RelativeSource Mode=FindAncestor, AncestorType={x:Type toolkit:Popup}}}"></Button> </Grid> <Grid ColumnDefinitions="*,*" ColumnSpacing="15" Padding="15,0,15,20"> <Entry Placeholder="City name" Text="{Binding CityName}" Grid.Column="0" TextColor="Snow"></Entry> <Button Text="Search" Command="{Binding SearchCommand}" CommandParameter="{Binding Source={RelativeSource Mode=FindAncestor, AncestorType={x:Type toolkit:Popup}}}" Grid.Column="1"></Button> </Grid> <CollectionView IsVisible="{Binding IsSearched}" ItemsSource="{Binding CityChoices}"> <CollectionView.ItemTemplate> <DataTemplate x:DataType="model:CityInfo"> <VerticalStackLayout HorizontalOptions="FillAndExpand" Padding="10,20,10,20" HeightRequest="100"> <VerticalStackLayout.GestureRecognizers> <TapGestureRecognizer CommandParameter="{Binding .}" Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodel:SetStaticLocalizationPopupViewModel}}, Path=SetChosenCityCommand}"></TapGestureRecognizer> </VerticalStackLayout.GestureRecognizers> <Label Style="{StaticResource CityInfoLabel}"> <Label.Text> <MultiBinding StringFormat="{}{0} - {1}"> <Binding Path="CityName"></Binding> <Binding Path="CountryName"></Binding> </MultiBinding> </Label.Text> </Label> <Label Style="{StaticResource CityInfoLabel}"> <Label.Text> <MultiBinding StringFormat="{}({0} | {1})"> <Binding Path="Lat"></Binding> <Binding Path="Lon"></Binding> </MultiBinding> </Label.Text> </Label> </VerticalStackLayout> </DataTemplate> </CollectionView.ItemTemplate> <CollectionView.EmptyView> <Label IsVisible="{Binding IsSearched}" Text="Failed to find city with that name" Style="{StaticResource CityInfoLabel}" Padding="10,20,10,20" TextColor="OrangeRed"></Label> </CollectionView.EmptyView> </CollectionView> </VerticalStackLayout> </toolkit:Popup>
解决方案
针对Windows平台的布局限制问题,可尝试以下几种修复方式:
1. 动态绑定CollectionView高度
在ViewModel中添加计算属性,根据CityChoices的数量动态计算高度(每个Item的HeightRequest为100,可根据实际调整):
public int CollectionViewHeight => CityChoices.Count * 100;
然后在XAML中绑定到CollectionView的HeightRequest:
<CollectionView IsVisible="{Binding IsSearched}" ItemsSource="{Binding CityChoices}" HeightRequest="{Binding CollectionViewHeight}">
2. 调整Popup与内部布局的VerticalOptions
Windows平台的Popup设置VerticalOptions="Center"可能限制高度扩展,修改为平台差异化配置:
<toolkit:Popup ... VerticalOptions="{OnPlatform Default='Center', WinUI='Fill'}">
同时将内部VerticalStackLayout的VerticalOptions改为Start,让内容从顶部自动扩展:
<VerticalStackLayout ... VerticalOptions="Start">
3. 用ScrollView包裹CollectionView
为CollectionView添加ScrollView容器,确保内容超出时可滚动,同时让Popup感知内容高度:
<ScrollView VerticalOptions="FillAndExpand" MaximumHeightRequest="{OnPlatform WinUI='400'}"> <CollectionView IsVisible="{Binding IsSearched}" ItemsSource="{Binding CityChoices}"> <!-- 保留原有CollectionView内容 --> </CollectionView> </ScrollView>
4. 手动触发Popup布局更新
在搜索命令执行完成后,调用Popup的InvalidateMeasure()强制重新计算布局:
public ICommand SearchCommand => new Command<Popup>(async (popup) => { // 原有搜索逻辑,填充CityChoices CityChoices = await GetCitiesAsync(CityName); // 强制Popup重新计算布局 popup.Dispatcher.Dispatch(() => { popup.InvalidateMeasure(); }); });
内容的提问来源于stack exchange,提问作者Bartosz Zięba
相关产品推荐
相关产品推荐

