如何使用Xamarin Forms创建具有垂直粘性标题和水平粘性第一列的表?

问题描述 投票:0回答:1

[显示表格数据时,我认为在某些情况下具有始终可见的标题行和始终可见的第一列确实可以提高表的可读性和整体可用性,尤其是当表中有很多数据时。当表格必须同时支持水平和垂直滚动时,就会发生此问题。在查看过去比赛的得分时,可以从NBA应用程序中找到此类表格的一个很好的示例。这是来自NBA Android应用程序的示例图像:Example table from NBA mobile application

您可以从图像中清楚地看到,标题行与实际表数据水平对齐,而第一列与表数据垂直对齐。我不知道这是一个自愿还是自愿的决定,以防止以相同的触摸动作水平和垂直滚动,但这只是我所关心的很小的细节。

我不知道如何使用Xamarin Forms来实现。我对封闭的源/付费解决方案不感兴趣,因为我想实际学习如何自己完成此工作。我确实意识到,我很可能必须为Android和IOS使用自定义渲染器。我目前的想法是我有一个绝对的布局,其中包含以下元素:

  • 第一个单元格(它是固定的,也是唯一的固定物体)
  • 水平滚动视图中标题行的其余部分
  • 列表视图/堆栈布局+垂直滚动视图内的第一列
  • 列表视图中的实际表数据+水平滚动视图/堆栈布局+水平和垂直滚动视图

通过此设置,我将捕获触摸事件并将其发送到其他列表视图/滚动视图,从而同步滚动。实际上,通过将表数据设置在与第一列相同的垂直滚动视图中,我可以轻松实现与第一列和实际表数据的同步滚动。但是我不知道如何将水平滚动同步到标题行,并且我确实相信这不可能通过聪明的组件结构来完成。到目前为止,我仅在Android上进行了测试,以便可以在scrollview自定义渲染器的OnTouchEvent-方法中捕获触摸事件,但是我不知道如何将其从自定义渲染器发送到标题行scrollview。

这是说明我的方法的XAML草案。

<AbsoluteLayout xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             HorizontalOptions="FillAndExpand">
    <ScrollView
        Orientation="Horizontal"
        x:Name="HeaderScrollView"
        AbsoluteLayout.LayoutBounds="0,0,1,1"
        AbsoluteLayout.LayoutFlags="All">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="200" />
                <ColumnDefinition Width="100" />
                <ColumnDefinition Width="100" />
                <ColumnDefinition Width="100" />
                <ColumnDefinition Width="100" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="50" />
            </Grid.RowDefinitions>
            <!-- Skip first column, leave it empty for stationary cell -->
            <Label Text="Column 1" Grid.Row="0" Grid.Column="1" />
            <Label Text="Column 2" Grid.Row="0" Grid.Column="2" />
            <Label Text="Column 3" Grid.Row="0" Grid.Column="3" />
            <Label Text="Column 4" Grid.Row="0" Grid.Column="4" />
        </Grid>
    </ScrollView>
    <ScrollView
        x:Name="FirstColumnScrollView"
        Orientation="Vertical"
        AbsoluteLayout.LayoutBounds="0,50,1,1"
        AbsoluteLayout.LayoutFlags="SizeProportional"
        BackgroundColor="Aqua">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="200" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <StackLayout
                Grid.Column="0"
                Grid.Row="0"
                BindableLayout.ItemsSource="{Binding DataSource}">
                <BindableLayout.ItemTemplate>
                    <DataTemplate>
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="50" />
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="150" />
                            </Grid.ColumnDefinitions>
                            <Label Text="{Binding Column1}" Grid.Row="0" Grid.Column="0" />
                        </Grid>
                    </DataTemplate>
                </BindableLayout.ItemTemplate>
            </StackLayout>
            <ScrollView
                x:Name="TableDataScrollView"
                Grid.Column="1"
                Grid.Row="0"
                Orientation="Horizontal">
                <StackLayout
                    BindableLayout.ItemsSource="{Binding DataSource}">
                    <BindableLayout.ItemTemplate>
                        <DataTemplate>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="100" />
                                    <ColumnDefinition Width="100" />
                                    <ColumnDefinition Width="100" />
                                    <ColumnDefinition Width="100" />
                                </Grid.ColumnDefinitions>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="50" />
                                </Grid.RowDefinitions>
                                <Label Text="{Binding Column2}" Grid.Row="0" Grid.Column="0" />
                                <Label Text="{Binding Column3}" Grid.Row="0" Grid.Column="1" />
                                <Label Text="{Binding Column4}" Grid.Row="0" Grid.Column="2" />
                                <Label Text="{Binding Column5}" Grid.Row="0" Grid.Column="3" />
                            </Grid>
                        </DataTemplate>
                    </BindableLayout.ItemTemplate>
                </StackLayout>
            </ScrollView>
        </Grid>
    </ScrollView>
    <Label Text="First Column" BackgroundColor="White" AbsoluteLayout.LayoutBounds="0,0,200,50" />
</AbsoluteLayout>

正如您所看到的问题是,HeaderScrollView和TableDataScrollView之间的水平滚动事件没有共享,而且我不知道如何以最佳方式或根本不实现此目的。

我非常感谢所有帮助和反馈!

[显示表格数据时,我认为在某些情况下具有始终可见的标题行和始终可见的第一列确实可以提高表的可读性和整体可用性,...

xamarin xamarin.forms scrollview tabular
1个回答
0
投票
您正在寻找的是具有冻结行和冻结列功能的DataGrid组件。有些第三方组件可以满足您的要求。
© www.soinside.com 2019 - 2024. All rights reserved.