Xamarin表单-一张内部包含ListView的卡片的高度非常大
我有一个包含项目的ListView,其中一个项目是一个包含ListView的DataTemplate 这里的问题是,这个数据模板在没有任何需要的情况下呈现得非常高 以下是结果截图的链接: 代码如下:Xamarin表单-一张内部包含ListView的卡片的高度非常大,listview,xamarin.forms,nested,Listview,Xamarin.forms,Nested,我有一个包含项目的ListView,其中一个项目是一个包含ListView的DataTemplate 这里的问题是,这个数据模板在没有任何需要的情况下呈现得非常高 以下是结果截图的链接: 代码如下: <?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm="clr-namespace:MyNotes.ViewModels"
xmlns:converters="clr-namespace:MyNotes.Converters"
xmlns:behaviors="clr-namespace:MyNotes.Behavior"
xmlns:selectors="clr-namespace:MyNotes.Selectors"
x:Class="MyNotes.Views.MainView">
<ContentPage.Resources>
<converters:CollectionEmptyConverter x:Key="CollectionEmptyConverter"/>
<DataTemplate x:Key="StringTemplate">
<ViewCell>
<Label Text="{Binding}"/>
</ViewCell>
</DataTemplate>
<DataTemplate x:Key="DefaultItemTemplate">
<ViewCell>
<Frame OutlineColor="Black" Margin="10">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Label Text="{Binding Title}" FontAttributes="Bold"/>
<Label Text="Unknow Item" Margin="0,10,0,0" Grid.Row="1"/>
</Grid>
</Frame>
</ViewCell>
</DataTemplate>
<DataTemplate x:Key="TodoItemTemplate">
<ViewCell>
<Frame OutlineColor="Black" Margin="10">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Label Text="{Binding Title}" FontAttributes="Bold"/>
<Label Text="{Binding Content}" Margin="0,10,0,0" Grid.Row="1"/>
</Grid>
</Frame>
</ViewCell>
</DataTemplate>
<DataTemplate x:Key="ListItemTemplate">
<ViewCell>
<Frame OutlineColor="Black">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Label Text="{Binding Title}"
FontAttributes="Bold"/>
<ListView ItemsSource="{Binding Items}"
Margin="0,10,0,0"
Grid.Row="1"
ItemTemplate="{StaticResource StringTemplate}"/>
</Grid>
</Frame>
</ViewCell>
</DataTemplate>
<selectors:ItemTypeSelector x:Key="ItemTypeSelector"
TodoItemTemplate="{StaticResource TodoItemTemplate}"
ListItemTemplate="{StaticResource ListItemTemplate}"/>
</ContentPage.Resources>
<ContentPage.BindingContext>
<vm:MainViewModel/>
</ContentPage.BindingContext>
<ContentPage.Content>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Label Text="No notes yet. Add some."
IsVisible="{Binding Collection, Converter={StaticResource CollectionEmptyConverter}}"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" />
<ListView ItemsSource="{Binding Collection}"
IsVisible="{Binding Collection, Converter={StaticResource CollectionEmptyConverter}, ConverterParameter=true}"
ItemTemplate="{StaticResource ItemTypeSelector}"/>
</Grid>
</ContentPage.Content>
</ContentPage>
我在几个地方读到过,这个问题很可能与我在DataTemplate的ListView中有一个ListView这一事实有关。
因为它是一个项目集合,其中一些项目可以包含一个项目列表,所以我不知道如何解决这个问题
任何帮助方向都会很好
谢谢
编辑:
我用一个小得多的例子验证了一个理论
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ListView ItemsSource="{Binding Collection}"
BackgroundColor="Yellow"/>
<Label Text="bla bla bla"
Grid.Row="1"/>
</Grid>
在本例中,我假设listview只占据所需的位置,但它没有占据整个应用程序的高度,我看不到文本bla bla bla bla。
为什么会有这种行为?我找到了解决我第一个问题的方法,任何帮助方向都会很好。 我在这里发现了一个github项目,它做得非常好。 它给了我一个ItemsControl,我可以为它分配一个源和一个item模板。我把它包装在一个ScrollView中,得到了一个可以正常工作的ListView 下面是一个示例用法:
<ScrollView>
<!-- Place new controls here -->
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<controls:ItemsControl ItemsSource="{Binding Collection}"
BackgroundColor="Beige">
<controls:ItemsControl.ItemTemplate>
<DataTemplate>
<ContentView>
<Frame OutlineColor="Black" HasShadow="True" IsClippedToBounds="True" Margin="10">
<StackLayout>
<Label Text="{Binding Title}"
FontAttributes="Bold"/>
<ScrollView>
<controls:ItemsControl ItemsSource="{Binding InnerCollection}"
Margin="10,0,0,0"/>
</ScrollView>
</StackLayout>
</Frame>
</ContentView>
</DataTemplate>
</controls:ItemsControl.ItemTemplate>
</controls:ItemsControl>
<!--<ListView ItemsSource="{Binding Collection}"
BackgroundColor="Yellow"/>-->
<Label Text="bla bla bla"
Grid.Row="1"/>
</Grid>
</ScrollView>
至于我的第二个问题,为什么会有这种行为我仍然不知道答案,但至少我可以对你的第二个问题取得进展:
在代码段中,第一行的高度设置为“自动”,这意味着
对象的大小应调整为布局中的可用大小,以便
第一行的大小将适合其内容
而ListView就在这一行,在这种情况下,ListView将自动填充整个屏幕以适应其内容
第二行设置为*,这意味着
计算自动行后,该行将获得
剩余高度
因此,在计算自动行之后,标签的剩余高度为0。这就是为什么您甚至看不到文本bla-bla-bla
我通过在代码隐藏中查看ListView和标签的高度来验证这一结论
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
this.SizeChanged += MainPage_SizeChanged;
}
private void MainPage_SizeChanged(object sender, EventArgs e)
{
//ListView height
Double a = myListView.Height;
//Label height
Double b = myLabel.Height;
}
}
结果如下:这里的第一个答案描述了这种行为的原因。默认情况下,ListView设置为填充所有可用空间。您需要将其大小或其容器的大小设置为特定值。您可以考虑在运行时动态地执行此操作,如果该高度将是可变的。最终,它以这种方式工作的原因是,通常认为嵌套ListView的设计很糟糕。您可能想更仔细地思考一下这里的交互模型。谢谢,我知道,我只是问他们为什么给ListView额外的高度,而不是内容需要的高度,因为它是可测量的。它是在WPF中完成的,所以也可以在这里完成,以给我们更好的体验。在我看来,ListView并不总是调整自身大小以适应其内容。它是一个滚动容器,能够通过滚动而不是最初调整自身大小来显示其所有单元格。单元格的数量永远不会影响其高度。因此,当您将“自动”设置为“行定义”时,ListView将自动填充整个屏幕以适应其内容,而不是提供内容所需的高度。我刚刚检查了它在WPF中的行为,我刚刚注意到它的行为更糟。在您回答并了解ListView在WPF中的行为后,我理解您的观点和Xamarin impl。这可能是最好的解决办法。
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
this.SizeChanged += MainPage_SizeChanged;
}
private void MainPage_SizeChanged(object sender, EventArgs e)
{
//ListView height
Double a = myListView.Height;
//Label height
Double b = myLabel.Height;
}
}