使用For循环创建带DataGridView的用户控件时数据源布尔值异常
解决DataGridView布尔列值被最后一个实例覆盖的问题
看起来你遇到的是典型的共享成员导致的引用覆盖问题,结合你描述的“仅最后一个值正确,前面的都被覆盖”的现象,我来帮你一步步排查解决:
最可能的根源:Finding类的布尔属性是Shared(共享)成员
如果你的Finding类里的Required或IsWarranty被定义成了Shared字段/属性,那么所有Finding实例都会共用同一个值——最后创建的那个实例的布尔值会覆盖之前所有实例的设置,这就解释了为什么调试时单个实例的值正确,但窗体显示后所有行都变成了最后一个值。
错误示例(你可能正在用的):
Public Class Finding ' 错误:Shared会让所有实例共用同一个变量 Public Shared Required As Boolean Public Shared IsWarranty As Boolean Public Property Description As String Public Property SolutionString As String End Class
修正方案:
把Shared改成实例属性,让每个Finding对象拥有独立的布尔值:
Public Class Finding ' 正确:每个实例有自己的属性值 Public Property Required As Boolean Public Property IsWarranty As Boolean Public Property Description As String Public Property SolutionString As String End Class
额外的优化建议(避免绑定冲突)
即使修正了属性定义,也建议你在绑定数据源时创建集合的副本,避免多个DataGridView意外共享同一个集合引用导致的潜在问题:
在TestEvalutionResult的构造函数里,把直接绑定改成创建副本:
' 原来的代码 .DataSource = test.Findings ' 改成创建独立副本 .DataSource = New List(Of OtherClass.Finding)(test.Findings)
可选:动态创建DataGridView列(更可靠)
如果你依赖设计时的列索引,可能会因为列顺序调整导致绑定错误。建议动态创建列,明确指定每个列的类型和绑定属性:
Public Sub New(test as OtherClass.Test) ' 必须先调用InitializeComponent初始化用户控件 InitializeComponent() ' 清除设计时的列,避免冲突 DataGridView1.Columns.Clear() ' 添加文本列 DataGridView1.Columns.Add(New DataGridViewTextBoxColumn() With { .HeaderText = "Description", .DataPropertyName = "Description", .AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells }) DataGridView1.Columns.Add(New DataGridViewTextBoxColumn() With { .HeaderText = "Solution", .DataPropertyName = "SolutionString", .AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells }) ' 添加布尔复选框列 DataGridView1.Columns.Add(New DataGridViewCheckBoxColumn() With { .HeaderText = "Required", .DataPropertyName = "Required", .AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells, .TrueValue = True, .FalseValue = False }) DataGridView1.Columns.Add(New DataGridViewCheckBoxColumn() With { .HeaderText = "Is Warranty", .DataPropertyName = "IsWarranty", .AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells, .TrueValue = True, .FalseValue = False }) ' 绑定独立的数据源副本 DataGridView1.DataSource = New List(Of OtherClass.Finding)(test.Findings) DataGridView1.DefaultCellStyle.WrapMode = DataGridViewTriState.True End Sub
最后检查点
确保你的用户控件构造函数里第一行调用了InitializeComponent()——这是WinForms用户控件初始化的必要步骤,漏掉的话会导致控件无法正确加载。
内容的提问来源于stack exchange,提问作者Norcel
相关产品推荐
相关产品推荐

