cs代码
public partial class Form1 : Form
{
private List<ComboBoxItem> sexItems = new List<ComboBoxItem>
{
new ComboBoxItem { Text = "男", Value = 0 },
new ComboBoxItem { Text = "女", Value = 1 },
new ComboBoxItem { Text = "管理员 (不可用)", Value = 99, IsEnabled = false },
new ComboBoxItem { Text = "访客", Value = 2, IsEnabled = true }
};
public Form1()
{
InitializeComponent();
this.dataGridView1.AutoGenerateColumns = false;
this.dataGridView1.EditMode = DataGridViewEditMode.EditOnEnter;
this.dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
// 注册事件
this.dataGridView1.EditingControlShowing += DataGridView1_EditingControlShowing;
this.dataGridView1.CellClick += (s, e) =>
{
if (e.RowIndex >= 0 && e.ColumnIndex >= 0)
{
var combo = dataGridView1.Columns[e.ColumnIndex] as DataGridViewComboBoxColumn;
if (combo != null)
{
dataGridView1.BeginEdit(false);
if (dataGridView1.EditingControl is DataGridViewComboBoxEditingControl cb)
{
cb.DroppedDown = true;
}
}
var textbox = dataGridView1.Columns[e.ColumnIndex] as DataGridViewTextBoxColumn;
if (textbox != null)
{
dataGridView1.BeginEdit(true);
}
}
};
// 设置数据源
this.dataGridView1.DataSource = StudentData.GetStudentList();
// 配置 ComboBox 列:使用 DataSource,而不是 Items.Add
colSex.DataPropertyName = "Sex";
colSex.DisplayMember = "Text";
colSex.ValueMember = "Value";
colSex.DataSource = sexItems; // ✅ 正确方式设置下拉数据源
}
private void DataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if (dataGridView1.CurrentCell.ColumnIndex == colSex.Index && e.Control is ComboBox comboBox)
{
// 移除之前的事件,防止重复订阅
comboBox.SelectedIndexChanged -= ComboBox_SelectedIndexChanged;
comboBox.DrawItem -= ComboBox_DrawItem;
comboBox.MeasureItem -= ComboBox_MeasureItem;
comboBox.SelectedIndexChanged += ComboBox_SelectedIndexChanged;
comboBox.DrawItem += ComboBox_DrawItem;
comboBox.MeasureItem += ComboBox_MeasureItem;
// 启用自定义绘制
comboBox.DrawMode = DrawMode.OwnerDrawFixed;
// 获取当前行
int rowIndex = dataGridView1.CurrentCell.RowIndex;
// 获取动态下拉项
//var items = GetItemsForRow(rowIndex);
// 设置数据源
//comboBox.DataSource = items;
//comboBox.DisplayMember = "Text";
//comboBox.ValueMember = "Value";
// 尝试选中当前值
var currentValue = dataGridView1.Rows[rowIndex].Cells[colSex.Name].Value;
var selectedItem = (comboBox.DataSource as List<ComboBoxItem>).FirstOrDefault(i => i.Value.Equals(currentValue));
if (selectedItem != null)
{
comboBox.SelectedItem = selectedItem;
}
// 保存当前值,用于后续比较(防止选择禁用项)
comboBox.Tag = currentValue;
}
}
private void ComboBox_DrawItem(object sender, DrawItemEventArgs e)
{
if (e.Index < 0) return;
var comboBox = sender as ComboBox;
var item = comboBox.Items[e.Index] as ComboBoxItem;
// ✅ 替代 Brushes.Highlight
Color backColor = (e.State & DrawItemState.Selected) == DrawItemState.Selected
? SystemColors.Highlight // 高亮色(系统蓝色)
: SystemColors.Window; // 背景色
using (var brush = new SolidBrush(backColor))
{
e.Graphics.FillRectangle(brush, e.Bounds);
}
// ✅ 文本颜色:禁用项为灰色
Color textColor = item.IsEnabled ? SystemColors.ControlText : SystemColors.GrayText;
using (var brush = new SolidBrush(textColor))
{
using (var sf = new StringFormat { LineAlignment = StringAlignment.Center, FormatFlags = StringFormatFlags.NoWrap })
{
sf.Trimming = StringTrimming.EllipsisCharacter;
e.Graphics.DrawString(item.Text, e.Font, brush, e.Bounds, sf);
}
}
// 绘制焦点框(如果需要)
if ((e.State & DrawItemState.Focus) == DrawItemState.Focus)
{
e.DrawFocusRectangle();
}
}
private void ComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
if (sender is ComboBox comboBox &&
comboBox.SelectedItem is ComboBoxItem selectedItem)
{
// 获取之前保存的值
if (comboBox.Tag is int previousValue)
{
// 检查当前选择的项是否被禁用
if (!selectedItem.IsEnabled)
{
// 弹出提示
MessageBox.Show("该项不可选择!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
// 还原选择
var items = comboBox.DataSource as List<ComboBoxItem>;
var oldItem = items.FirstOrDefault(i => i.Value == previousValue);
if (oldItem != null)
{
comboBox.SelectedItem = oldItem;
}
// 防止脏数据
dataGridView1.NotifyCurrentCellDirty(false);
}
else
{
// 合法选择,更新 Tag
comboBox.Tag = selectedItem.Value;
}
}
}
}
private void ComboBox_MeasureItem(object sender, MeasureItemEventArgs e)
{
// 设置每项高度
e.ItemHeight = 22;
}
private List<ComboBoxItem> GetItemsForRow(int rowIndex)
{
var list = new List<ComboBoxItem>
{
new ComboBoxItem { Text = "男", Value = 0, IsEnabled = true },
new ComboBoxItem { Text = "女", Value = 1, IsEnabled = true }
};
list.Add(new ComboBoxItem { Text = "管理员 (不可用)", Value = 99, IsEnabled = false });
list.Add(new ComboBoxItem { Text = "访客", Value = 2, IsEnabled = true });
return list;
}
}
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public int Sex { get; set; }
public string Address { get; set; }
}
public class StudentData
{
public static List<Student> GetStudentList()
{
List<Student> list = new List<Student>();
list.Add(new Student() { Id = 1, Name = "张三", Sex = 0, Address = "上海" });
list.Add(new Student() { Id = 2, Name = "李四", Sex = 1, Address = "北京" });
list.Add(new Student() { Id = 3, Name = "王五", Sex = 0, Address = "广州" });
list.Add(new Student() { Id = 4, Name = "赵六", Sex = 1, Address = "深圳" });
return list;
}
}
public class ComboBoxItem
{
public int Value { get; set; }
public string Text { get; set; }
public bool IsEnabled { get; set; } = true; // 默认可用
// ✅ 必须重写 ToString,否则 ComboBox 显示类名
public override string ToString()
{
return Text ?? Value.ToString();
}
}
设计器代码
partial class Form1
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.dataGridView1 = new System.Windows.Forms.DataGridView();
this.colId = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.colSex = new System.Windows.Forms.DataGridViewComboBoxColumn();
this.colName = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.colAdress = new System.Windows.Forms.DataGridViewTextBoxColumn();
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
this.SuspendLayout();
//
// dataGridView1
//
this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.colId,
this.colSex,
this.colName,
this.colAdress});
this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill;
this.dataGridView1.EnableHeadersVisualStyles = false;
this.dataGridView1.Location = new System.Drawing.Point(0, 0);
this.dataGridView1.Name = "dataGridView1";
this.dataGridView1.RowHeadersWidth = 51;
this.dataGridView1.RowTemplate.Height = 27;
this.dataGridView1.Size = new System.Drawing.Size(800, 450);
this.dataGridView1.TabIndex = 0;
//
// colId
//
this.colId.DataPropertyName = "Id";
this.colId.HeaderText = "编号";
this.colId.MinimumWidth = 6;
this.colId.Name = "colId";
this.colId.Width = 125;
//
// colSex
//
this.colSex.HeaderText = "性别";
this.colSex.MinimumWidth = 6;
this.colSex.Name = "colSex";
this.colSex.Width = 125;
//
// colName
//
this.colName.DataPropertyName = "Name";
this.colName.HeaderText = "姓名";
this.colName.MinimumWidth = 6;
this.colName.Name = "colName";
this.colName.Resizable = System.Windows.Forms.DataGridViewTriState.True;
this.colName.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
this.colName.Width = 125;
//
// colAdress
//
this.colAdress.DataPropertyName = "Address";
this.colAdress.HeaderText = "地址";
this.colAdress.MinimumWidth = 6;
this.colAdress.Name = "colAdress";
this.colAdress.Width = 125;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.dataGridView1);
this.Name = "Form1";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Form1";
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.DataGridView dataGridView1;
private System.Windows.Forms.DataGridViewTextBoxColumn colId;
private System.Windows.Forms.DataGridViewComboBoxColumn colSex;
private System.Windows.Forms.DataGridViewTextBoxColumn colName;
private System.Windows.Forms.DataGridViewTextBoxColumn colAdress;
}
浙公网安备 33010602011771号