You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何向预定义行列的WPF Grid添加列表数据并实现TextBlock居中显示

问题原因

你之前用WrapPanel作为ListBox的条目容器无法满足需求,是因为WrapPanel是根据元素尺寸自动换行,不能严格匹配你预定义的固定8列6行网格结构,也无法让条目精准对应到预设的单元格位置。
以下是两种可行的实现方案:


方案1:代码后置实现(适合简单场景,分页、边框扩展方便)

首先给你的Grid添加名称,方便后置代码操作:

<Grid x:Name="SerialGrid" Grid.Row="1">
    <!-- 保留你原有的8列6行定义 -->
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
        <ColumnDefinition/>
        <ColumnDefinition/>
        <ColumnDefinition/>
        <ColumnDefinition/>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
        <RowDefinition/>
        <RowDefinition/>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>
</Grid>

在数据源加载完成、或者分页切换时调用填充方法:

private void FillSerialGrid()
{
    // 清空现有内容,分页切换时可复用
    SerialGrid.Children.Clear();
    var dataSource = Serials.ToList();
    // 每页最多8*6=48个单元格
    int maxCount = 48;

    for (int i = 0; i < Math.Min(dataSource.Count, maxCount); i++)
    {
        // 计算当前数据对应的行列位置
        int rowIndex = i / 8;
        int colIndex = i % 8;

        // 创建TextBlock并设置居中
        var textBlock = new TextBlock
        {
            Text = dataSource[i].aaa,
            HorizontalAlignment = HorizontalAlignment.Center,
            VerticalAlignment = VerticalAlignment.Center
        };
        // 如果需要加单元格边框,直接把TextBlock包在Border控件里即可
        // var border = new Border { BorderBrush = Brushes.Gray, BorderThickness = new Thickness(1), Child = textBlock };

        // 设置元素的单元格位置,添加到Grid中
        Grid.SetRow(textBlock, rowIndex);
        Grid.SetColumn(textBlock, colIndex);
        SerialGrid.Children.Add(textBlock);
        // 如果用了Border,就把上面的textBlock换成border即可
    }
}

方案2:MVVM绑定实现(符合MVVM规范,无需后置代码)

使用ItemsControl作为容器,直接把你预设的Grid作为条目面板,通过绑定自动计算每个条目的行列位置:

1. 先创建行列索引转换器

// 索引转行号转换器
public class IndexToRowConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is int index && parameter is string colStr && int.TryParse(colStr, out int columnCount))
            return index / columnCount;
        return 0;
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException();
}

// 索引转列号转换器
public class IndexToColumnConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is int index && parameter is string colStr && int.TryParse(colStr, out int columnCount))
            return index % columnCount;
        return 0;
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException();
}

2. XAML代码实现

<!-- 页面资源中注册转换器 -->
<Page.Resources>
    <local:IndexToRowConverter x:Key="IndexToRowConverter"/>
    <local:IndexToColumnConverter x:Key="IndexToColumnConverter"/>
</Page.Resources>

<!-- 绑定控件部分 -->
<ItemsControl ItemsSource="{Binding CurrentPageSerials}" Grid.Row="1">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <!-- 你预设的8列6行Grid -->
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                </Grid.RowDefinitions>
            </Grid>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <!-- 绑定每个条目的行列位置 -->
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
            <Setter Property="Grid.Row" Value="{Binding (ItemsControl.AlternationIndex), RelativeSource={RelativeSource Self}, Converter={StaticResource IndexToRowConverter}, ConverterParameter=8}"/>
            <Setter Property="Grid.Column" Value="{Binding (ItemsControl.AlternationIndex), RelativeSource={RelativeSource Self}, Converter={StaticResource IndexToColumnConverter}, ConverterParameter=8}"/>
        </Style>
    </ItemsControl.ItemContainerStyle>
    <!-- 条目模板,直接设置TextBlock居中,可直接加边框 -->
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Border BorderBrush="Gray" BorderThickness="1">
                <TextBlock Text="{Binding aaa}"
                           HorizontalAlignment="Center"
                           VerticalAlignment="Center"
                           Margin="20"/>
            </Border>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

分页功能实现

只需要在ViewModel中维护当前页码属性,页码变化时重新计算CurrentPageSerials(当前页展示的最多48条数据的子集)即可,无需修改界面代码。


内容的提问来源于stack exchange,提问作者ShuSong Lu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 16:15:03