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

如何在WPF DataGrid中复用列定义,避免重复实现高尔夫成绩列

复用WPF DataGrid球洞列的两种实用方案

当然可以复用列定义,不用重复写18遍DataGridTemplateColumn。下面给出两种落地性强的实现方式:

方案一:后台代码动态生成列(最直接高效)

如果你的DataGrid绑定的球员对象包含HoleScores集合(比如List<int>或ObservableCollection<int>),可以通过循环批量创建列,统一复用模板逻辑:

// 定义通用的单元格显示模板
var cellTemplate = new DataTemplate();
var textBlockFactory = new FrameworkElementFactory(typeof(TextBlock));
cellTemplate.VisualTree = textBlockFactory;

// 定义通用的单元格编辑模板
var editingTemplate = new DataTemplate();
var textBoxFactory = new FrameworkElementFactory(typeof(TextBox));
textBoxFactory.SetValue(TextBox.BorderThicknessProperty, new Thickness(0));
editingTemplate.VisualTree = textBoxFactory;

// 循环生成18个球洞列
for (int holeIndex = 0; holeIndex < 18; holeIndex++)
{
    var column = new DataGridTemplateColumn
    {
        Header = $"第{holeIndex + 1}洞",
        CellTemplate = cellTemplate,
        CellEditingTemplate = editingTemplate
    };

    // 绑定对应索引的HoleScores值
    var displayBinding = new Binding($"HoleScores[{holeIndex}]");
    textBlockFactory.SetBinding(TextBlock.TextProperty, displayBinding);

    var editBinding = new Binding($"HoleScores[{holeIndex}]") 
    { 
        UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged 
    };
    textBoxFactory.SetBinding(TextBox.TextProperty, editBinding);

    MyDataGrid.Columns.Add(column);
}

注意:如果HoleScores是ObservableCollection,绑定会自动响应集合变更;若为普通List,需手动触发属性变更通知。

方案二:XAML资源+附加属性(纯声明式实现)

  1. 先创建一个附加属性类,用来传递球洞索引:
public static class HoleColumnHelper
{
    public static readonly DependencyProperty HoleIndexProperty =
        DependencyProperty.RegisterAttached("HoleIndex", typeof(int), typeof(HoleColumnHelper), 
            new PropertyMetadata(0, OnHoleIndexChanged));

    public static int GetHoleIndex(DependencyObject obj)
    {
        return (int)obj.GetValue(HoleIndexProperty);
    }

    public static void SetHoleIndex(DependencyObject obj, int value)
    {
        obj.SetValue(HoleIndexProperty, value);
    }

    private static void OnHoleIndexChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is DataGridTemplateColumn column)
        {
            // 更新显示模板的绑定
            if (column.CellTemplate.LoadContent() is TextBlock tb)
            {
                tb.SetBinding(TextBlock.TextProperty, 
                    new Binding($"HoleScores[{(int)e.NewValue}]"));
            }
            // 更新编辑模板的绑定
            if (column.CellEditingTemplate.LoadContent() is TextBox tbEdit)
            {
                tbEdit.SetBinding(TextBox.TextProperty, 
                    new Binding($"HoleScores[{(int)e.NewValue}]") 
                    { UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged });
            }
        }
    }
}
  1. 在XAML中定义通用模板资源,然后引用并指定球洞索引:
<Window.Resources>
    <DataTemplate x:Key="HoleCellTemplate">
        <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </DataTemplate>
    <DataTemplate x:Key="HoleCellEditingTemplate">
        <TextBox HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </DataTemplate>
</Window.Resources>

<DataGrid x:Name="MyDataGrid" AutoGenerateColumns="False">
    <!-- 总杆、净杆列 -->
    <DataGridTextColumn Header="总杆" Binding="{Binding Gross}" Width="80"/>
    <DataGridTextColumn Header="净杆" Binding="{Binding NetOrPoints}" Width="80"/>
    
    <!-- 复用球洞列,仅需修改Header和HoleIndex -->
    <DataGridTemplateColumn Header="第1洞" local:HoleColumnHelper.HoleIndex="0"
                            CellTemplate="{StaticResource HoleCellTemplate}"
                            CellEditingTemplate="{StaticResource HoleCellEditingTemplate}"/>
    <DataGridTemplateColumn Header="第2洞" local:HoleColumnHelper.HoleIndex="1"
                            CellTemplate="{StaticResource HoleCellTemplate}"
                            CellEditingTemplate="{StaticResource HoleCellEditingTemplate}"/>
    <!-- ... 依次添加到第18洞 -->
</DataGrid>

两种方案都能彻底避免重复编写列模板,方案一适合代码驱动的场景,方案二更贴合XAML声明式开发的习惯,可根据项目需求选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.11 14:03:18