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;
}
posted on 2025-10-21 21:21  魔法乐  阅读(4)  评论(0)    收藏  举报