我希望当用户点击一个单元格时出现一个OpenFileDialog,然后在单元格中显示结果。
这一切都有效,除了DataGridView显示一个额外的行,用于将值添加到它所绑定的列表中。该行显示dataGridView.AllowUserToAddNewRows == true
,这就是我想要的。我不想要的是当以编程方式编辑该行时应用程序崩溃;相反,它应该完全按照用户手动编辑该行的方式(将新行添加到基础列表,将另一个空行推入网格以添加值)。
我读到了SendKeys.Send(),它应该使DataGridView的行为与用户输入的值完全相同;但是,它也不起作用。这是我正在尝试的:
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
dataGridView1.CurrentCell = cell;
//simply doing a cell.Value = etc. will cause the program to crash
cell.ReadOnly = false;
dataGridView1.Columns[cell.ColumnIndex].ReadOnly = false;
dataGridView1.EditMode = DataGridViewEditMode.EditOnEnter;
dataGridView1.BeginEdit(true);
SendKeys.Send(openFileDialog1.FileName + "{Enter}");
dataGridView1.EndEdit();
cell.ReadOnly = true;
dataGridView1.Columns[cell.ColumnIndex].ReadOnly = true;
}
//I would expect the FileName would be in the cell now, and a new empty
//row tacked onto the end of the DataGridView, but it's not; the DataGridView
//is not changed at all.
答案 0 :(得分:16)
我在this page找到了解决方法,但我不知道它为什么会起作用
public MyForm()
{
InitializeComponent();
//Create a BindingSource, set its DataSource to my list,
//set the DataGrid's DataSource to the BindindingSource...
_bindingSource.AddingNew += OnAddingNewToBindingSource;
}
private void OnAddingNewToBindingSource(object sender, AddingNewEventArgs e)
{
if(dataGridView1.Rows.Count == _bindingSource.Count)
{
_bindingSource.RemoveAt(_bindingSource.Count - 1);
}
}
我非常厌倦花费这么多时间处理Visual Studio漏洞......
答案 1 :(得分:10)
当尝试使用绑定源编程编辑单元格时,我遇到了同样的问题。 “”由于对象的当前状态“
,操作无效哪个操作?什么状态?非常有帮助。
除了编辑网格中的最后一行外,我的代码似乎工作正常。
原来关键是DataGridView.NotifiyCurrentCelldirty(true)
以编程方式编辑单元格的正确顺序,因此它的工作方式与用户执行的顺序相同。 (更改最后一行中的单元格时出现一个新的空行)如下所示:
1)让单元格编辑当前单元格(首先执行当前当前单元格所需的操作) 比如调用endEdit,如果它处于编辑模式。)
2)调用DataGridview.BeginEdit(false)
3)调用DataGridView.NotifyCurrentCellDirty(true)
4)修改价值。
5)调用DataGridView.EndEdit()
你想要为RowValidating和RowValidated事件做点什么。
我更新单元格值的一个例程如下所示:
这是我从类DataGridView派生的类中的方法。 你可以从包含的表单做同样的事情,调用 通过DataGridView实例,因为方法是公共的。 这里的电话使用了一个隐含的“这个”。
private void EnterTime()
{
if (CurrentRow == null) return;
SaveCurrentCell(); // Calls EndEdit() if CurrentCell.IsInEditMode
DataGridViewCell previous = CurrentCell;
CurrentCell = CurrentRow.Cells[CatchForm.TimeColumn];
BeginEdit(false);
NotifyCurrentCellDirty(true);
CurrentCell.Value = DateTime.Now;
EndEdit();
CurrentCell = previous;
}
我不确定为什么需要单独打电话。
为什么没有BeginEdit,或实际修改单元格值,导致权利 要发生的事情?
如果您在实际修改单元格后移动NotifyCurrentCellDirty调用, 它的行为也不正确。一切都很烦人。
答案 2 :(得分:3)
这是旧的,但是我正在运行VS2010并且遇到了这个问题。我使用DataGridView
绑定了List<T>
BindingList<T>
。我的DataGridView
上有一个拖放事件,在删除DGV中的所有行(除了最后一个无法删除的空白行)和 >然后通过DragDrop
向BindingList<T>
处理程序中的DGV添加新行。如果我只是添加手动编辑单个单元格的行,则不会抛出此异常。
我读过的一个解决方案是处理BindingList<T>.AddNew
事件,但我发现在BindingList<T>.Add()
事件处理程序中调用DragDrop
时这个事件没有触发(我不知道为什么)。我通过添加
if(bindingList.Count == 0)
bindingList.RemoveAt(0)
>向DragDrop
添加新对象之前, 1内的bindingList
事件处理程序。当bindingList
中唯一的“对象”是与最后一个空行相关联的对象时,似乎向bindingList
添加对象失败了。 BindingList<T>
的要点是允许开发人员直接使用代替 DGV,但似乎这样做会导致边界情况出现问题。
DGV行和BindingList<T>
行之间的关系似乎有点像灰色区域。我没有花太多时间来研究这个问题,但我不清楚与DGV的最后(空)行相关联的BindingList<T>
中的“对象”的状态是什么。但是,当你直接与最后一行(而不是通过DataSource
)进行交互时,它看起来似乎只是“正确”实例化了“对象”。
答案 3 :(得分:1)
试试这个:
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
int row = e.RowIndex;
int clmn = e.ColumnIndex;
if(e.RowIndex == dataGridView1.Rows.Count- 1)
dataGridView1.Rows.Add();
dataGridView1.Rows[row].Cells[clmn].Value = openFileDialog1.FileName;
}
修改强> 我没注意到你绑定了你的datagridview :( 好的,要解决它:使用绑定源,将其DataSource属性设置为列表,然后将数据网格视图的数据源设置为此绑定源。现在,代码应如下所示:
public partial class frmTestDataGridView : Form
{
BindingSource bindingSource1 = new BindingSource();
List<string> datasource = new List<string>();
public frmTestDataGridView()
{
InitializeComponent();
datasource.Add("item1");
datasource.Add("item2");
datasource.Add("item3");
bindingSource1.DataSource = datasource;
dataGridView1.DataSource = bindingSource1;
}
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
int row = e.RowIndex;
int clmn = e.ColumnIndex;
if (e.RowIndex == dataGridView1.Rows.Count - 1)
{
bindingSource1.Add("");
}
dataGridView1.Rows[row].Cells[clmn].Value = openFileDialog1.FileName;
}
}
}
答案 4 :(得分:0)
如果在编辑行中的值时出现此错误,请使用Row.BeginEdit()
和Row.EndEdit()
,使用来自Janus的DataGrid或GridEX(在我的情况下)。 Darrel Lee在这里发布的示例代码(https://stackoverflow.com/a/9143590/1278771)提醒我使用我忘记使用的这些说明,这解决了我的问题。