我在 CollectionView 中有一个 Expander

I have an Expander in a CollectionView

我对宠物有 collection 的看法。带有图像和名称。当您单击名称时,它会启用扩展器,您可以查看宠物的详细信息。这有一个缺点。自然地,当扩展器扩展时它占用 space 但是当它扩展时,它占用的 space 只是留空是否可以摆脱这个 space?

我的 Collection 查看:

<CollectionView x:Name="PetCollection" ItemsSource="{Binding EmptyPetInfo}" Margin="65,0,10,0" HeightRequest="400">
                <CollectionView.ItemsLayout>
                    <GridItemsLayout Orientation="Vertical"
                                     Span="2" />
                </CollectionView.ItemsLayout>
                <CollectionView.ItemTemplate>
                    <DataTemplate>

                        <Grid x:Name="PetCollectionGrid" Padding="0" ColumnDefinitions="140,140" >
                            <Grid.RowDefinitions>
                                <RowDefinition Height = "140"/>
                                <RowDefinition Height = "5"/>
                                <RowDefinition Height = "20*"/>
                            </Grid.RowDefinitions>
                            <xct:AvatarView Source="{Binding imageUrl}"                 
                                                       VerticalOptions="Center"
                                                       HorizontalOptions="Center"
                                                       Size="100"
                                                       CornerRadius="50"
                                            Aspect="AspectFill">
                            </xct:AvatarView>
                            <BoxView Color="Gray"
                                         HeightRequest="2"
                                         HorizontalOptions="Fill" Grid.Row="1" />
                            <xct:Expander Grid.Row="2" Tapped="Expander_Tapped">
                                <xct:Expander.Header>
                                    <Label Text="{Binding PetName}"
                                        HorizontalTextAlignment="Center"/>
                                </xct:Expander.Header>
                                <Grid RowDefinitions="20*,20*,20*,20*">
                                    <Label Text="{Binding Breed}"/>
                                    <Label Text="{Binding DOB}" Grid.Row="1"/>
                                    <Label Text="{Binding Gender}" Grid.Row="2"/>
                                    <Label Text="{Binding Weight}" Grid.Row="3"/>
                                </Grid>
                            </xct:Expander>
                            
                        </Grid>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>

所以一点点更新我在点击的扩展器中添加了这段代码。但是,这仅适用于最后一行的扩展器。当它展开时需要 space 当它关闭时 space 消失。中间和顶部的扩展器在扩展时会占用 space,但在关闭时仍会留下空白 space.

 private void Expander_Tapped(object sender, EventArgs e)
     {
         Expander Expander = sender as Expander;
         Grid grid = (Grid)Expander.Parent;
         int index = Grid.GetRow(Expander);
         RowDefinition rowdef = grid.RowDefinitions[index];
         if (Expander.IsEnabled)
         {
             rowdef.Height = new GridLength(1,
         Expander.IsExpanded ? GridUnitType.Star : GridUnitType.Auto);
         }
         else
         {
             rowdef.Height = new GridLength(0,
         !Expander.IsExpanded ? GridUnitType.Absolute : GridUnitType.Absolute);
         }
     }

Expander doc“众所周知,Expander 控件在 ListView 或 CollectionView 中使用时会显示不需要的行为。此时我们建议不要在其中一个控件中使用 Expander。” .

一种可能的解决方法是“替换”绑定集合中的项目,强制重新绘制布局。

可能还有其他方法可以强制重绘该项目。

目前在 collection 视图中使用扩展器会给您带来各种麻烦。我使用的解决方法是使用像 stacklayout 或带有可绑定布局的网格这样的容器来替换 collection 视图。 如果您的 collection 物品数量有限,这会非常有效。如果您有一个大 collection,这不是一个好的选择,您应该考虑更改设计以不使用扩展器。

https://devblogs.microsoft.com/xamarin/xamarin-forms-bindable-layout/

我能够使用您提供的代码重现此问题。当您向上滚动 AB 行时,它会删除白色 space。

一个简单的方法是使用 RefreshView 刷新页面。绑定一个 IsRefreshing 属性 来控制刷新。

Xaml:

  <RefreshView IsRefreshing="{Binding isRefreshing}">
    <CollectionView x:Name="PetCollection" ItemsSource="{Binding EmptyPetInfo}" Margin="65,0,10,0" HeightRequest="400">
        <CollectionView.ItemsLayout>
            <GridItemsLayout Orientation="Vertical"
                                 Span="2" />
        </CollectionView.ItemsLayout>
        <CollectionView.ItemTemplate>
            <DataTemplate>

                <Grid x:Name="PetCollectionGrid" ColumnDefinitions="140,140" >
                    <Grid.RowDefinitions>
                        <RowDefinition Height = "Auto"/>
                        <RowDefinition Height = "Auto"/>
                        <RowDefinition Height = "Auto"/>
                    </Grid.RowDefinitions>
                    <xct:AvatarView Source="{Binding imageUrl}"                 
                                                   VerticalOptions="Center"
                                                   HorizontalOptions="Center"
                                                   Size="100"
                                                   CornerRadius="50"
                                        Aspect="AspectFill">
                    </xct:AvatarView>
                    <BoxView Color="Gray"
                                     HeightRequest="2"
                                     HorizontalOptions="Fill" Grid.Row="1" />
                    <xct:Expander Grid.Row="2" Tapped="Expander_Tapped" >
                        <xct:Expander.Header>
                            <Label Text="{Binding PetName}"
                                    HorizontalTextAlignment="Center"/>
                        </xct:Expander.Header>
                        <Grid RowDefinitions="20*,20*,20*,20*">
                            <Label Text="{Binding Breed}"/>
                            <Label Text="{Binding DOB}" Grid.Row="1"/>
                            <Label Text="{Binding Gender}" Grid.Row="2"/>
                            <Label Text="{Binding Weight}" Grid.Row="3"/>
                        </Grid>
                    </xct:Expander>

                </Grid>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
</RefreshView>

后面的代码:

  public partial class MainPage : ContentPage
{
    public ObservableCollection<PetInfo> EmptyPetInfo { get; set; }
    public bool isRefreshing { get; set; }
    public MainPage()
    {
        InitializeComponent();
        isRefreshing = false;
        EmptyPetInfo = new ObservableCollection<PetInfo>()
        {
            new PetInfo(){ Breed="Breed1", DOB="DOB1", Gender="F", PetName="A", Weight="1", imageUrl="https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Papio_anubis_%28Serengeti%2C_2009%29.jpg/200px-Papio_anubis_%28Serengeti%2C_2009%29.jpg"},
            new PetInfo(){ Breed="Breed2", DOB="DOB2", Gender="M", PetName="B", Weight="2", imageUrl="https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Papio_anubis_%28Serengeti%2C_2009%29.jpg/200px-Papio_anubis_%28Serengeti%2C_2009%29.jpg"},
            new PetInfo(){ Breed="Breed3", DOB="DOB3", Gender="F", PetName="C", Weight="13", imageUrl="https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Papio_anubis_%28Serengeti%2C_2009%29.jpg/200px-Papio_anubis_%28Serengeti%2C_2009%29.jpg"},
            new PetInfo(){ Breed="Breed4", DOB="DOB4", Gender="M", PetName="D", Weight="14", imageUrl="https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Papio_anubis_%28Serengeti%2C_2009%29.jpg/200px-Papio_anubis_%28Serengeti%2C_2009%29.jpg"},
            new PetInfo(){ Breed="Breed5", DOB="DOB5", Gender="F", PetName="E", Weight="1", imageUrl="https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Papio_anubis_%28Serengeti%2C_2009%29.jpg/200px-Papio_anubis_%28Serengeti%2C_2009%29.jpg"},
            new PetInfo(){ Breed="Breed6", DOB="DOB6", Gender="F", PetName="F", Weight="15", imageUrl="https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Papio_anubis_%28Serengeti%2C_2009%29.jpg/200px-Papio_anubis_%28Serengeti%2C_2009%29.jpg"},
            new PetInfo(){ Breed="Breed7", DOB="DOB7", Gender="F", PetName="G", Weight="12", imageUrl="https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Papio_anubis_%28Serengeti%2C_2009%29.jpg/200px-Papio_anubis_%28Serengeti%2C_2009%29.jpg"},
            new PetInfo(){ Breed="Breed8", DOB="DOB8", Gender="M", PetName="H", Weight="61", imageUrl="https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Papio_anubis_%28Serengeti%2C_2009%29.jpg/200px-Papio_anubis_%28Serengeti%2C_2009%29.jpg"},
            new PetInfo(){ Breed="Breed9", DOB="DOB9", Gender="F", PetName="I", Weight="16", imageUrl="https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Papio_anubis_%28Serengeti%2C_2009%29.jpg/200px-Papio_anubis_%28Serengeti%2C_2009%29.jpg"},
            new PetInfo(){ Breed="Breed10", DOB="DO010", Gender="F", PetName="J", Weight="61", imageUrl="https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Papio_anubis_%28Serengeti%2C_2009%29.jpg/200px-Papio_anubis_%28Serengeti%2C_2009%29.jpg"},
            new PetInfo(){ Breed="Breed11", DOB="DOB11", Gender="M", PetName="K", Weight="11", imageUrl="https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Papio_anubis_%28Serengeti%2C_2009%29.jpg/200px-Papio_anubis_%28Serengeti%2C_2009%29.jpg"}

        };
        this.BindingContext = this;

    }

    private void Expander_Tapped(object sender, EventArgs e)
    {
        Expander Expander = sender as Expander;
        if (!Expander.IsExpanded)
        {
            isRefreshing = true;
        }
    }
}
public class PetInfo
{
    public string imageUrl { get; set; }
    public string PetName { get; set; }
    public string Breed { get; set; }
    public string DOB { get; set; }
    public string Gender { get; set; }
    public string Weight { get; set; }
}