如何使DataGridView立即提交编辑?

4
我有一个主从布局,其中有一部分是弹出菜单(详情),另一部分是包含行的DataGridView。
当DataGridView中选定的行更改时,弹出菜单状态会更新,并且当弹出菜单更改时,DGV中选定行的状态也应该更新。
所有这些都有效,除了DataGridView中的行在我更改弹出菜单的值时不会立即更新。我必须选择其他行才能看到我的编辑内容。
我认为这是因为在选择更改之前尚未提交编辑。
我的问题是:如何使弹出菜单中的更改立即反映在DataGridView中?
我已经尝试在SelectionChangeCommitted处理程序中调用EndEdit(),但没有效果。我希望找到一种技术,可以创建一个DataGridView,就像根本没有撤消机制一样。理想情况下,解决方案应是通用的,并可移植到其他项目中。
6个回答

7

看起来现有的答案对于 BindingSource 很有效。在我的情况下,DataTable 直接用作 DataSource,因某种原因它们并不起作用。

// Other answers didn't work in my setup...
private DataGridView dgv;

private Form1()
{
   var table = new DataTable();
   // ... fill the table ...
   dgv.DataSource = table;
}

经过一些挣扎,我成功地让它在不添加BindingSource间接性的情况下工作:

// Add this event handler to the DataGridView
private void dgv_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
    dgv.BindingContext[dgv.DataSource].EndCurrentEdit();
}

private Form1()
{
   dgv.CellEndEdit += dgv_CellEndEdit;
   // ...
}

这对我有用。我们希望每个单元格都能应用,而无需单击另一行。 - carny666

4
这是发生的情况。答案在ComboBox实例的属性中。我需要将它们的DataSourceUpdateModeOnValidation更改为OnPropertyChanged。这很有道理。DataGridView很可能显示数据的当前状态。只是因为焦点还没有离开ComboBox,所以输入还没有经过验证,数据还没有被编辑。
感谢大家的回复。

4

这对我很有效:

private void CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
    var dgw = (DataGridView) sender;
    dgw.CommitEdit(DataGridViewDataErrorContexts.Commit);
}

2

使用这个扩展方法。它适用于所有列类型,而不仅仅是ComboBoxes:

        public static void ChangeEditModeToOnPropertyChanged(this DataGridView gv)
        {
            gv.CurrentCellDirtyStateChanged += (sender, args) =>
            {
                gv.CommitEdit(DataGridViewDataErrorContexts.Commit);
                if (gv.CurrentCell == null)
                    return;
                if (gv.CurrentCell.EditType != typeof(DataGridViewTextBoxEditingControl))
                    return;
                gv.BeginEdit(false);
                var textBox = (TextBox)gv.EditingControl;
                textBox.SelectionStart = textBox.Text.Length;
            };
        }

这种方法在每次更改后立即提交所有更改。

当我们有一个文本列时,输入一个字符后,它的值将提交到数据源,并且单元格的编辑模式将结束。

因此,当前单元格应返回编辑模式,并将光标位置设置为文本末尾,以便用户可以继续输入其余的文本。


0

应该添加更多细节。我知道EndEdit会导致这种情况发生。为了知道何时调用它,我需要注意什么? - Michael Bishop
@MichaelBishop,可能需要在调用EndEdit之前等待当前消息分派完成。使用BeginInvoke(new Action(()=>dgv.EndEdit())。这是有效的,因为BeginInvoke使用PostMessage来发布WM_USER消息,WinForms消息泵使用它来实现BeginInvoke。 - Tergiver
谢谢。BeginInvoke(new Action(()=>dgv.EndEd‌​it())) 是唯一对我有效的方法。 - rayzinnz
1
即使使用BeginInvoke(new Action(() => dataGridView1.EndEdit()))也无法正常工作。 - Andrew_STOP_RU_WAR_IN_UA

-1

以下代码将有效运行

_dataGrid.EndEdit()

一旦设置了值,就很好。


不对,行不通 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接