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
相关产品推荐
相关产品推荐

