Xamarin表单-一张内部包含ListView的卡片的高度非常大

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/

我有一个包含项目的ListView,其中一个项目是一个包含ListView的DataTemplate

这里的问题是,这个数据模板在没有任何需要的情况下呈现得非常高

以下是结果截图的链接:

代码如下:

<?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;

        }
    }