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 初始化背后的代码 ... 这不是很清楚并且是错误的来源...
我有一个垂直堆栈布局的表单。它有两个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 初始化背后的代码 ... 这不是很清楚并且是错误的来源...