绑定DataTable的DataGridView中为ComboBox列启用SuggestAppend及自定义列复用问题
解决方案:DataTable绑定DataGridView时启用部分列的SuggestAppend并使用自定义列
你的需求完全可以实现,问题核心在于默认情况下DataGridView绑定DataTable时会自动生成列,直接覆盖了你手动创建的自定义列,导致ComboBox列的SuggestAppend设置没生效。下面一步步帮你解决问题:
关键原理与修改要点
- 关闭自动列生成:设置
$dataGrid.AutoGenerateColumns = $false,让DataGridView使用你手动定义的列,而非根据DataTable自动创建新列。 - 关联自定义列与数据源列:给每个自定义列设置
DataPropertyName,值对应DataTable中的列名(比如Employee和Status),确保数据源能正确映射到自定义列。 - 保留SuggestAppend逻辑:你之前写的
EditingControlShowing事件处理是正确的,只要确保触发该事件的是你自定义的ComboBox列,就能正常生效。
修改后的完整可运行代码
$mainForm = New-Object System.Windows.Forms.Form $mainForm.StartPosition = 'CenterScreen' $mainForm.FormBorderStyle = 'Fixed3D' $mainForm.Text = 'Test' $mainForm.WindowState = 'Maximized' $bounds = ($mainForm.CreateGraphics()).VisibleClipBounds.Size $dataGrid = New-Object System.Windows.Forms.DataGridView $dataGrid.Size = New-Object System.Drawing.Size(($bounds.Width-20),($bounds.Height-140)) $dataGrid.Location = New-Object System.Drawing.Size(10,60) $dataGrid.AllowUserToAddRows = $true $dataGrid.SelectionMode = 0 $dataGrid.MultiSelect = $true $dataGrid.ReadOnly = $false $dataGrid.RowHeadersVisible = $false $dataGrid.ColumnHeadersBorderStyle = 2 $dataGrid.EnableHeadersVisualStyles = $true # 关键修改1:关闭自动列生成,强制使用自定义列 $dataGrid.AutoGenerateColumns = $false # 创建Employee文本列并绑定DataTable对应列 $colEmployee = New-Object System.Windows.Forms.DataGridViewTextBoxColumn $colEmployee.Name = 'Employee' $colEmployee.HeaderText = 'Employee' $colEmployee.DataPropertyName = 'Employee' # 关联数据源列 $dataGrid.Columns.Add($colEmployee) # 创建Status下拉列并绑定DataTable对应列 $colStatus = New-Object System.Windows.Forms.DataGridViewComboBoxColumn $colStatus.Name = 'Status' $colStatus.HeaderText = 'Status' $colStatus.Items.AddRange('Active','Withdraw') $colStatus.DataPropertyName = 'Status' # 关联数据源列 $dataGrid.Columns.Add($colStatus) # 保留SuggestAppend自动补全逻辑 $dataGrid.Add_EditingControlShowing({ $box = $_.Control -as [System.Windows.Forms.ComboBox] if($box) { $box.DropDownStyle = [System.Windows.Forms.ComboBoxStyle]::DropDown $box.AutoCompleteMode = [System.Windows.Forms.AutoCompleteMode]::SuggestAppend } }) $dataGrid.AutoSizeColumnsMode = [System.Windows.Forms.DataGridViewAutoSizeColumnMode]::Fill $mainForm.Controls.Add($dataGrid) # 构建DataTable数据源 $source = @' Employee,Status user.example1,Active user.example2,Withdraw user.example3,Withdraw user.example4,Active '@ | ConvertFrom-Csv $columns = $source[0].PSobject.Properties.Name $table = New-Object System.Data.DataTable foreach($column in $columns) { $i = New-Object System.Data.DataColumn $i.DataType = [string] $i.ColumnName = $column $table.Columns.Add($i) } foreach($line in $source) { $row = $table.NewRow() foreach($column in $columns) { $row.$column = $line.$column } $table.Rows.Add($row) } # 绑定数据源到DataGridView $dataGrid.DataSource = $table $mainForm.Add_Shown({ $mainForm.Activate() }) $mainForm.ShowDialog()
效果说明
修改后你会看到:
- Status列保持ComboBox类型,输入时会自动触发
SuggestAppend补全(输入"A"会提示"Active",输入"W"会提示"Withdraw"); - DataTable中的数据正确显示在自定义列中,修改网格内容后,DataTable的数据也会同步更新,完全满足你修改后导出数据的需求。
内容的提问来源于stack exchange,提问作者Santiago Squarzon
相关产品推荐
相关产品推荐

