Xamarin 表单堆栈布局问题

Xamarin forms stacklayout issue

我有一个垂直堆栈布局的表单。它有两个children。第一个(最上面的)child 是一个条目。第二个 child 是列表视图。我的问题是我希望列表视图展开以填充屏幕上剩余的 space,然后可以滚动。如果没有为列表视图设置特定高度(这显然不适用于不同的屏幕尺寸),我一直无法实现这一点。如果我将列表视图的垂直选项设置为 FillAndExpand,它似乎会扩展到屏幕边缘,您无法滚动到列表视图中最底部的条目。在不设置特定高度的情况下如何实现这一目标?这个布局是在 C# 中动态生成的。 parent 堆栈布局的垂直选项也是 FillAndExpand。

我已经尝试按照@KFactory 的建议使用网格。当我这样做时,我得到了这个结果:

您可以看到底部有一个列表视图没有填充的空白。

这是要添加视图的页面:

 <?xml version="1.0" encoding="utf-8" ?>
    <local:BaseContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:local="clr-namespace:TecMan.MobileApp"
                 xmlns:f="clr- 
     namespace:TecMan.MobileApp.Behaviours;assembly=TecMan.MobileApp"
                 x:Class="TecMan.MobileApp.MainPage">
    <AbsoluteLayout x:Name="frmLayout" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" BackgroundColor="LightGray">
        <StackLayout
            Orientation="Vertical"
            HorizontalOptions="FillAndExpand"
            VerticalOptions="FillAndExpand">
            <Grid 
                x:Name="frmMain" 
                HorizontalOptions="FillAndExpand"
                VerticalOptions="FillAndExpand"
                RowSpacing="0">
                <local:BaseContentPage.Behaviors>
                    <f:BindingChangedBehaviour/>
                </local:BaseContentPage.Behaviors>
            </Grid>
        </StackLayout>
    </AbsoluteLayout>
    </local:BaseContentPage>

正在将控件添加到网格中'frmMain'

后面的代码中正在动态添加控件(内容因场景而异)。控件的行/列和网格位置定义如下:

 Grid frmMain = page as Grid;  //page.FindByName<Grid>("frmMain");
                if (frmMain == null) throw new NotImplementedException("Only support Grid");

                frmMain.ColumnDefinitions.Clear();
                frmMain.ColumnDefinitions.Add(new ColumnDefinition
                {
                     Width = new GridLength(1, GridUnitType.Star)
                });

                frmMain.RowDefinitions.Clear();
                frmMain.RowDefinitions.Add(new RowDefinition
                {
                    Height = new GridLength(1, GridUnitType.Auto)
                });
                frmMain.RowDefinitions.Add(new RowDefinition
                {
                    Height = new GridLength(1, GridUnitType.Star)
                });

            Grid.SetColumn(btnFrame, 0);
            Grid.SetRow(btnFrame, 0);

            Grid.SetColumn(oViewColumn, 0);
            Grid.SetRow(oViewColumn, 1);

第一个控件是一个包裹在框架中的条目。第二个控件是自定义列表视图,其 xaml 是:

<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="TecMan.MobileViewModels.Controls.CollapsibleListView"
              xmlns:local="clr-namespace:TecMan.MobileViewModels.Controls;assembly=TecMan.MobileViewModels"  >
    <ContentView.Content
       BackgroundColor="LightGrey" >

        <ListView
             VerticalOptions="FillAndExpand"
             BackgroundColor="White" 
            HasUnevenRows="True"
            RowHeight="-1"
            x:Name="collapseLV"
            MinimumHeightRequest="1000"
             ItemsSource="{Binding Items}" >
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <local:CollapsibleGridView  Title="{Binding Title}"
                                                    TitleColour="#99ff66"  
                                                    ButtonVisible="{Binding ButtonVisible}" 
                                                    CaptionField="{Binding CaptionField}" 
                                                    DataField="{Binding DataField}" 
                                                    IsHiddenField="{Binding IsHiddenField}" 
                                                    ButtonColour="{Binding ButtonColour}"                                                   
                                                    VisibleItemsColour="{Binding VisibleItemsColour}" 
                                                    HiddenItemsColour="{Binding HiddenItemsColour}" 
                                                    CellBackgroundColor="{Binding CellBackgroundColor}" 
                                                    ImageFile="{Binding ImageFile}"    
                                                    ItemsSource="{Binding}">
                        </local:CollapsibleGridView>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>

        </ListView>



    </ContentView.Content>
</ContentView>

Xamarin Forms(还)不如 WPF 强大...有一些 'unnatural' 行为。 在我的例子中,我曾经像这样使用网格控件:

<Grid RowSpacing="0">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <!-- Row 0: your entry />
    <Entry Grid.Row="0" ... />

    <!-- Row 1: your Listview that will take all available remaining space /> 
    <Listview Grid.Row="1"
        ...
        />
</Grid>

请注意,网格的 'RowSpacing' 属性 设置为“0”以避免控件之间出现空 space。 现在应该可以工作了...


编辑 1(完整 xaml 代码):

<?xml version="1.0" encoding="utf-8" ?>
<local:BaseContentPage xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:TecMan.MobileApp"
    xmlns:f="clr- 
     namespace:TecMan.MobileApp.Behaviours;assembly=TecMan.MobileApp"
                 x:Class="TecMan.MobileApp.MainPage">

    <!-- Set your page's behavior here -->
    <local:BaseContentPage.Behaviors>
        <f:BindingChangedBehaviour/>
    </local:BaseContentPage.Behaviors>

    <!-- Set directly a grid as content of your page -->
    <Grid 
        x:Name="frmMain" 
        BackgroundColor="LightGray"
        RowSpacing="0">

        <Grid.RowDefinitions>
            <RowDefinition x:Name="r1" Height="Auto" />
            <RowDefinition x:Name="r2" Height="*" />
        </Grid.RowDefinitions>

        <!-- Row 0: your entry />
        <Entry Grid.Row="0" ... />

        <!-- Row 1: your Listview that will take all available remaining space /> 
        <local:CollapsibleListView 
            Grid.Row="1"
            ...
            />

    </Grid>
</local:BaseContentPage>

在后面的代码中使用行名称 ('r1' & 'r2') 添加您的控件。

但是 我建议你不要混合使用 XAML 和 UI 初始化背后的代码 ... 这不是很清楚并且是错误的来源...