如何在Xamarin.Forms.DataGrid中实现首列横向滚动时固定
实现Xamarin.Forms.DataGrid首列横向滚动固定的思路
你使用的Xamarin.Forms.DataGrid控件本身没有内置首列固定的功能,下面是两种可行的实现思路,其中第一种是更易上手的共享代码方案:
方案一:双DataGrid拆分布局
通过将表格拆分为两个独立的DataGrid,分别承载固定首列和可滚动的其余列,再同步两者的行为来实现效果:
- 用
Grid容器将页面分为左右两部分,左侧放置仅包含首列的DataGrid,右侧放置包含剩余列的DataGrid,两者绑定同一数据源 - 同步垂直滚动:监听两个DataGrid内部ListView的滚动事件,让它们的滚动位置保持一致
- 统一视觉样式:确保两个DataGrid的行高、表头样式、行背景色等完全一致,避免视觉割裂
- 同步选中状态:当其中一个DataGrid的选中项变化时,同步设置另一个的选中项
示例XAML代码
<Grid> <!-- 固定首列的DataGrid --> <dg:DataGrid x:Name="FixedDataGrid" ItemsSource="{Binding Details}" SelectionEnabled="True" SelectedItem="{Binding SelectedProfesstional, Mode=TwoWay}" RowHeight="70" HeaderHeight="50" BorderColor="#CCCCCC" HeaderBackground="#E0E6F8" ActiveRowColor="#8899AA" HorizontalScrollBarVisibility="Never" Scrolled="FixedDataGrid_Scrolled"> <x:Arguments> <ListViewCachingStrategy>RetainElement</ListViewCachingStrategy> </x:Arguments> <dg:DataGrid.HeaderFontSize> <OnIdiom x:TypeArguments="x:Double"> <OnIdiom.Tablet>15</OnIdiom.Tablet> <OnIdiom.Phone>12</OnIdiom.Phone> </OnIdiom> </dg:DataGrid.HeaderFontSize> <dg:DataGrid.Columns> <dg:DataGridColumn PropertyName="Name" Width="3*"> <dg:DataGridColumn.FormattedTitle> <FormattedString> <Span Text="User Name" FontSize="13" TextColor="Black" FontAttributes="Bold" /> </FormattedString> </dg:DataGridColumn.FormattedTitle> </dg:DataGridColumn> </dg:DataGrid.Columns> <dg:DataGrid.RowsBackgroundColorPalette> <dg:PaletteCollection> <Color>#F2F2F2</Color> <Color>#FFFFFF</Color> </dg:PaletteCollection> </dg:DataGrid.RowsBackgroundColorPalette> </dg:DataGrid> <!-- 可横向滚动的DataGrid --> <ScrollView Grid.Column="1" HorizontalScrollBarVisibility="Always"> <dg:DataGrid x:Name="ScrollableDataGrid" ItemsSource="{Binding Details}" SelectionEnabled="True" SelectedItem="{Binding SelectedProfesstional, Mode=TwoWay}" RowHeight="70" HeaderHeight="50" BorderColor="#CCCCCC" HeaderBackground="#E0E6F8" PullToRefreshCommand="{Binding RefreshCommand}" IsRefreshing="{Binding IsRefreshing}" ActiveRowColor="#8899AA" VerticalScrollBarVisibility="Never" Scrolled="ScrollableDataGrid_Scrolled"> <x:Arguments> <ListViewCachingStrategy>RetainElement</ListViewCachingStrategy> </x:Arguments> <dg:DataGrid.HeaderFontSize> <OnIdiom x:TypeArguments="x:Double"> <OnIdiom.Tablet>15</OnIdiom.Tablet> <OnIdiom.Phone>12</OnIdiom.Phone> </OnIdiom> </dg:DataGrid.HeaderFontSize> <dg:DataGrid.Columns> <dg:DataGridColumn Title="User Email" PropertyName="Email" Width="2*"/> <dg:DataGridColumn Title="User Phone" PropertyName="Number" Width="1*"/> </dg:DataGrid.Columns> <dg:DataGrid.RowsBackgroundColorPalette> <dg:PaletteCollection> <Color>#F2F2F2</Color> <Color>#FFFFFF</Color> </dg:PaletteCollection> </dg:DataGrid.RowsBackgroundColorPalette> </dg:DataGrid> </ScrollView> </Grid>
代码-behind同步滚动
private void FixedDataGrid_Scrolled(object sender, ScrolledEventArgs e) { var scrollableListView = ScrollableDataGrid.GetListView(); scrollableListView.ScrollToAsync(e.ScrollX, e.ScrollY, false); } private void ScrollableDataGrid_Scrolled(object sender, ScrolledEventArgs e) { var fixedListView = FixedDataGrid.GetListView(); fixedListView.ScrollToAsync(e.ScrollX, e.ScrollY, false); }
方案二:自定义平台渲染器
针对iOS和Android分别编写自定义渲染器,修改原生表格控件的行为来实现首列固定:
- Android端可基于RecyclerView实现双列表联动,iOS端可使用UITableView配合UIScrollView实现固定列
- 这种方案体验更接近原生控件,但需要对平台原生开发有一定了解,开发成本较高
内容的提问来源于stack exchange,提问作者Raj
相关产品推荐
相关产品推荐

