我在 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; }
}
我对宠物有 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; }
}