我有一个带有几个DataGridViewComboBoxColumns的DataGridView。只需单击一下下拉组合框,即可在DataGridView上使用CellEnter事件处理程序。

该列绑定(bind)到KeyValuePairs列表,其中ValueMember为“键”,而DisplayMember为“Value”。

当我单击组合框列时,它可以正常工作。但是,如果单元格处于“下拉”状态,并且我单击另一个组合框(同一列,不同的行),它将正确地取消选择旧单元格,选择并下拉新单元格,但是顶部的选定值将更改为更改回正确的值之前,请先将旧单元格中的值保留一秒钟。

例如,假设列表为A,B,C。在第1行中,选择了A,在第2行中,选择了B。我单击row1中的单元格,一切如预期。然后,在该单元格被下拉的同时,我单击第2行中的单元格。它会正确下降,但最上面的选定值将变为A,然后立即切换回B(正确的值)。

如果在单击第二个组合框单元格之前单击其他列中的单元格,则不会发生这种情况。

有办法防止这种情况发生吗?

重现问题的示例代码(事件处理程序与明显的事件相关联):

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace PDGV
{
    public partial class Form1 : Form
    {
        List<KeyValuePair<string, string>> bindingList = new List<KeyValuePair<string, string>>();

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            dataGridView1.Rows.Add(10);
            bindingList.Add(new KeyValuePair<string,string>("aaa", "111"));
            bindingList.Add(new KeyValuePair<string,string>("bbb", "222"));
            bindingList.Add(new KeyValuePair<string,string>("ccc", "333"));
            bindingList.Add(new KeyValuePair<string,string>("ddd", "444"));
            bindingList.Add(new KeyValuePair<string,string>("eee", "555"));
            BindComboList(2, bindingList);

        }

        private void BindComboList(int columnIndex, object list)
        {
            var column = dataGridView1.Columns[columnIndex] as DataGridViewComboBoxColumn;
            if (column != null)
            {
                column.DataSource = new BindingSource(list, null);
                column.DisplayMember = "Value";
                column.ValueMember = "Key";
            }
        }

        private void dataGridView1_CellEnter(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex == -1)
                return;

            dataGridView1.BeginEdit(true);
            var control = dataGridView1.EditingControl as DataGridViewComboBoxEditingControl;
            if (control != null)
                control.DroppedDown = true;
        }
    }
}

最佳答案

原因:

深入到DataGridView的EndEdit方法中,它存储以前使用的EditingControl this.latestEditingControl = this.editingControl;的副本。然后,当您开始编辑另一个单元格时,它将插入BeginEditInternal。在此过程中,它检查LatestEditingControl是否不为null且编辑类型是否与最后一个单元格相同,如果是,它将重用该控件,这就是您看到Flash的原因,它实际上是同一控件。

解决方案:

将latestEditingControl设置为null,则无法通过常规属性/方法访问此控件,必须使用反射。注意:这会导致完全不同的烦恼,现在您要离开的单元格会闪烁白色:),但确实可以解决您寻求帮助的特定问题。

    private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
    {
        if (e.RowIndex == -1)
            return;

        //this.latestEditingControl
        Type t = dataGridView1.GetType();
        FieldInfo viewSetter = t.GetField("latestEditingControl", BindingFlags.Default | BindingFlags.NonPublic | BindingFlags.Instance);
        viewSetter.SetValue(dataGridView1, null);
    }

关于c# - DataGridViewComboBoxColumn-值滞后一秒钟,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11465857/

10-11 17:58