选择后 DataGridViewComboBoxCell 显示 Value 成员而不是 Display 成员

Posted

技术标签:

【中文标题】选择后 DataGridViewComboBoxCell 显示 Value 成员而不是 Display 成员【英文标题】:DataGridViewComboBoxCell shows Value member and not Display member after selection 【发布时间】:2018-05-30 19:12:36 【问题描述】:

所以我一直在研究 DataGridView,用户可以在其中更改一行中一个单元格的值,然后将同一行中另一个单元格的类型更改为 DataGridViewComboBoxCell 或返回 DataGridViewTextBoxCell。我可以让组合框像这样显示。

Dictionary<long, string> InspectionTools = new Dictionary<long, string>();

private void DynamicControlsDGV_CellValueChanged(object sender, DataGridViewCellEventArgs e)

    if (DynamicControlsDGV.Columns[e.ColumnIndex].Name == "typeDataGridViewTextBoxColumn")
    
        var type = int.Parse(DynamicControlsDGV[1, e.RowIndex].Value.ToString());
        if (type == 8)
        
            var CBCell = new DataGridViewComboBoxCell();
            CBCell.DataSource = InspectionTools.ToList();
            CBCell.ValueMember = "Key";
            CBCell.DisplayMember = "Value";
            CBCell.DisplayStyle = DataGridViewComboBoxDisplayStyle.ComboBox;
            DynamicControlsDGV[7, e.RowIndex] = CBCell;
        
        else
        
            var CBCell = new DataGridViewTextBoxCell();
            DynamicControlsDGV[7, e.RowIndex] = CBCell;
        
    

然而,即使我在单击组合框单元格时看到了所有值,但当我选择我想要的那个时,单元格会显示值成员(键/ID)而不是显示成员(值/名称)。如下图:

有没有办法可以覆盖单元格格式,使其不会将显示文本更改回 ID?

最小、完整且可验证的示例

创建 MCVE 后,我发现问题出在我的代码中的其他地方。这是我做参考的 MSVE(效果很好):

代码背后:

public partial class Form1 : Form

    public List<KeyValuePair<long, string>> options2 = new List<KeyValuePair<long, string>>();
    public Form1()
    
        InitializeComponent();
        var options = new List<KeyValuePair<long, string>>();
        options.Add(new KeyValuePair<long, string>(1, "text"));
        options.Add(new KeyValuePair<long, string>(2, "combo"));

        options2 = new List<KeyValuePair<long, string>>();
        options2.Add(new KeyValuePair<long, string>(1, "option 1"));
        options2.Add(new KeyValuePair<long, string>(2, "option 2"));

        ((DataGridViewComboBoxColumn)dataGridView1.Columns[0]).DataSource = options;
        ((DataGridViewComboBoxColumn)dataGridView1.Columns[0]).ValueMember = "Key";
        ((DataGridViewComboBoxColumn)dataGridView1.Columns[0]).DisplayMember = "Value";
        for (int i = 0; i < 5; i++)
        
            DataGridViewRow row = (DataGridViewRow)dataGridView1.Rows[0].Clone();
            dataGridView1.Rows.Add(row);
        
    

    private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
    
        if (e.ColumnIndex==0)
        
            try
            
                if (int.Parse(dataGridView1[e.ColumnIndex, e.RowIndex].Value.ToString()) == 2)
                
                    var CBCell = new DataGridViewComboBoxCell();
                    CBCell.DataSource = options2;
                    CBCell.ValueMember = "Key";
                    CBCell.DisplayMember = "Value";
                    CBCell.DisplayStyle = DataGridViewComboBoxDisplayStyle.ComboBox;
                    dataGridView1[1, e.RowIndex] = CBCell;
                
                else
                
                    var CBCell = new DataGridViewTextBoxCell();
                    dataGridView1[1, e.RowIndex] = CBCell;
                
            
            catch
            
            
        
    

设计师:

partial class Form1

    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    
        if (disposing && (components != null))
        
            components.Dispose();
        
        base.Dispose(disposing);
    

    #region Windows Form Designer generated code

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    
        this.dataGridView1 = new System.Windows.Forms.DataGridView();
        this.Column2 = new System.Windows.Forms.DataGridViewComboBoxColumn();
        this.Column3 = 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.Column2,
        this.Column3);
        this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill;
        this.dataGridView1.Location = new System.Drawing.Point(0, 0);
        this.dataGridView1.Name = "dataGridView1";
        this.dataGridView1.Size = new System.Drawing.Size(879, 564);
        this.dataGridView1.TabIndex = 0;
        this.dataGridView1.CellValueChanged += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellValueChanged);
        // 
        // Column2
        // 
        this.Column2.HeaderText = "2";
        this.Column2.Name = "Column2";
        // 
        // Column3
        // 
        this.Column3.HeaderText = "3";
        this.Column3.Name = "Column3";
        // 
        // Form1
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(879, 564);
        this.Controls.Add(this.dataGridView1);
        this.Name = "Form1";
        this.Text = "Form1";
        ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
        this.ResumeLayout(false);

    

    #endregion

    private System.Windows.Forms.DataGridView dataGridView1;
    private System.Windows.Forms.DataGridViewComboBoxColumn Column2;
    private System.Windows.Forms.DataGridViewTextBoxColumn Column3;

另一个更新

我将 Dictionary 从 Dictionary 更改为 Dictionary,因为我的原始示例将 long 更改为字符串,因为它所基于的类将 string 作为 InstrumentName 的类型(我正在编辑的列)。因此,在单元格中设置的字符串值无法匹配它们在字典中的长键。

【问题讨论】:

无法重现该问题。考虑发布minimal reproducible example。 我看对了吗:一个单元工作而另一个不工作?所以,寻找差异应该是关键.. 仪器名称列默认为文本列。我将一个单元格更改为组合框单元格(3)。组合框显示并在单击时显示正确的值。选择值后,它会在第 4 部分中显示 ID(值成员)而不是名称(显示成员)。顺便说一句,它一直保留为文本,直到我单击另一个单元格,所以我相信单元格格式中的某些内容会导致它像默认值一样被格式化文本框单元格。 你说得对,Reza,在较小的规模上它确实有效。我将查看 datagridview 属性,以防其中一个可能导致此问题。 【参考方案1】:

数据网格视图基于通过 LINQ to SQL 创建的类。因此,列类型设置为字符串,而不是默认的 Object。将组合框的数据源更改为字符串对后,字符串单元格的格式正确。

【讨论】:

以上是关于选择后 DataGridViewComboBoxCell 显示 Value 成员而不是 Display 成员的主要内容,如果未能解决你的问题,请参考以下文章

选择后隐藏 UIPicker

用户选择后的API调用

选择后引导日期选择器返回焦点

UIImagePicker 选择后崩溃

MPMediaPickerController - 错误选择后取消选择

使用多项选择 select2 选择后立即显示选择的选项数量