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

WPF中重复调用dtFillDatagrid致DataGrid列重复的解决方法

解决WPF DataGrid重复列问题及优化DataTable绑定方式

一、直接解决重复列问题

核心问题是每次调用dtFillDatagrid时,仅清空了数据但未清除之前手动添加的列,导致重复累加。只需在添加新列前,保留XAML定义的CheckBox列,移除其余旧列即可:

修改dtFillDatagrid方法,加入列清理逻辑:

Function dtFillDatagrid(ByVal dt As DataTable, ByVal dgv As DataGrid) As Boolean
    dgv.ItemsSource = Nothing
    Dim myUI As userInterface = New userInterface

    Try
        ' 保留XAML的CheckBox列,移除其他所有旧列
        While dgv.Columns.Count > 1
            dgv.Columns.RemoveAt(1)
        End While

        For Each column As DataColumn In dt.Columns
            Dim name As String = column.ColumnName
            If name = "IsSelected" Then
            ElseIf name = "sn" Then
                dgv.Columns.Add(myUI.DataGridText(name, name, True))            
            Else
                dgv.Columns.Add(myUI.DataGridText(name, name))
            End If
        Next
        ' 先设置自动生成列属性,再绑定数据源
        dgv.AutoGenerateColumns = False
        dgv.CanUserAddRows = False
        dgv.ItemsSource = dt.DefaultView
        Return True
    Catch ex As Exception
        logUtil.e(ex)
        Return False
    End Try
End Function

二、更便捷的DataTable绑定方式

手动维护列集合容易出错,推荐利用DataGrid的自动列生成特性,结合事件自定义列行为,彻底避免重复列问题:

1. 修改XAML配置

保留CheckBox列,开启自动生成列并绑定事件:

<DataGrid x:Name="boxNoDetail" 
          IsReadOnly="true" 
          ItemsSource="{Binding}" 
          HorizontalScrollBarVisibility="Auto" 
          VerticalScrollBarVisibility="Auto" 
          FontSize="12"
          AutoGenerateColumns="True"
          AutoGeneratingColumn="boxNoDetail_AutoGeneratingColumn">
    <DataGrid.Columns>
        <DataGridCheckBoxColumn Header="Checked"  
                                Binding="{Binding IsChecked, UpdateSourceTrigger=PropertyChanged}">
            <DataGridCheckBoxColumn.ElementStyle>
                <Style TargetType="{x:Type CheckBox}" BasedOn="{StaticResource {x:Type CheckBox}}">
                    <Setter Property="VerticalAlignment" Value="Center"/>
                    <Setter Property="HorizontalAlignment" Value="Center"/>
                    <Setter Property="IsHitTestVisible" Value="False"/>
                </Style>
            </DataGridCheckBoxColumn.ElementStyle>
        </DataGridCheckBoxColumn>
    </DataGrid.Columns>
</DataGrid>

2. 后台实现列自定义逻辑

在窗口/用户控件后台添加事件处理,控制列的显示、样式:

Private Sub boxNoDetail_AutoGeneratingColumn(sender As Object, e As DataGridAutoGeneratingColumnEventArgs)
    Dim columnName As String = e.PropertyName
    ' 跳过不需要显示的列
    If columnName = "IsSelected" Then
        e.Cancel = True
        Return
    End If
    ' 设置列头文本
    e.Column.Header = columnName
    ' 隐藏sn列
    If columnName = "sn" Then
        e.Column.Visibility = Visibility.Hidden
        Return
    End If
    ' 可扩展:为指定列设置右对齐
    ' If columnName = "Amount" Then
    '     Dim textCol = TryCast(e.Column, DataGridTextColumn)
    '     If textCol IsNot Nothing Then
    '         Dim style As New Style(GetType(TextBox))
    '         style.Setters.Add(New Setter(TextBox.TextAlignmentProperty, TextAlignment.Right))
    '         textCol.CellStyle = style
    '     End If
    ' End If
End Sub

3. 简化绑定方法

现在绑定DataTable只需几行代码,无需手动添加列:

Function dtFillDatagrid(ByVal dt As DataTable, ByVal dgv As DataGrid) As Boolean
    Try
        dgv.CanUserAddRows = False
        dgv.ItemsSource = dt.DefaultView
        Return True
    Catch ex As Exception
        logUtil.e(ex)
        Return False
    End Try
End Function

这种方式利用WPF内置机制减少手动代码,既避免重复列问题,也更符合WPF设计思想。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 18:54:52