我有一个datagridview绑定到一个绑定源和一个窗体上的几个按钮。一个按钮将一个项目添加到绑定源,另一个按钮删除当前选定的项目。还有一个事件处理程序,用于侦听CurrentChanged事件并更新Remove按钮的Enabled状态。DataGridView绑定问题:“索引-1没有值。”
直到我去掉datagridview中的最后一项时,所有东西都是hunky dory。然后我看到一个很丑陋的例外:
at System.Windows.Forms.CurrencyManager.get_Item(Int32 index)
at System.Windows.Forms.CurrencyManager.get_Current()
at System.Windows.Forms.DataGridView.DataGridViewDataConnection.OnRowEnter(DataGridViewCellEventArgs e)
at System.Windows.Forms.DataGridView.OnRowEnter(DataGridViewCell& dataGridViewCell, Int32 columnIndex, Int32 rowIndex, Boolean canCreateNewRow, Boolean validationFailureOccurred)
at System.Windows.Forms.DataGridView.SetCurrentCellAddressCore(Int32 columnIndex, Int32 rowIndex, Boolean setAnchorCellAddress, Boolean validateCurrentCell, Boolean throughMouseClick)
at System.Windows.Forms.DataGridView.SetAndSelectCurrentCellAddress(Int32 columnIndex, Int32 rowIndex, Boolean setAnchorCellAddress, Boolean validateCurrentCell, Boolean throughMouseClick, Boolean clearSelection, Boolean forceCurrentCellSelection)\r\n at System.Windows.Forms.DataGridView.MakeFirstDisplayedCellCurrentCell(Boolean includeNewRow)
at System.Windows.Forms.DataGridView.OnEnter(EventArgs e)
at System.Windows.Forms.Control.NotifyEnter()
at System.Windows.Forms.ContainerControl.UpdateFocusedControl()
at System.Windows.Forms.ContainerControl.AssignActiveControlInternal(Control value)
at System.Windows.Forms.ContainerControl.ActivateControlInternal(Control control, Boolean originator)
at System.Windows.Forms.ContainerControl.SetActiveControlInternal(Control value)
at System.Windows.Forms.ContainerControl.SetActiveControl(Control ctl)
at System.Windows.Forms.ContainerControl.set_ActiveControl(Control value)
at System.Windows.Forms.Control.Select(Boolean directed, Boolean forward)
at System.Windows.Forms.Control.SelectNextControl(Control ctl, Boolean forward, Boolean tabStopOnly, Boolean nested, Boolean wrap)
at System.Windows.Forms.Control.SelectNextControlInternal(Control ctl, Boolean forward, Boolean tabStopOnly, Boolean nested, Boolean wrap)
at System.Windows.Forms.Control.SelectNextIfFocused()
at System.Windows.Forms.Control.set_Enabled(Boolean value)
at Bug3324.Form1.HandleBindingSourceCurrentChanged(Object _sender, EventArgs _e) in D:\\Dev\\TempApps\\Bug3324\\Bug3324\\Form1.cs:line 41
at System.Windows.Forms.BindingSource.OnCurrentChanged(EventArgs e)
at System.Windows.Forms.BindingSource.CurrencyManager_CurrentChanged(Object sender, EventArgs e)
at System.Windows.Forms.CurrencyManager.OnCurrentChanged(EventArgs e)
我隔离在一个小场景的问题:
private BindingSource m_bindingSource = new BindingSource();
public Form1()
{
InitializeComponent();
m_bindingSource.CurrentChanged += HandleBindingSourceCurrentChanged;
m_bindingSource.DataSource = new BindingList<StringValue>();
dataGridView1.DataSource = m_bindingSource;
btnAdd.Click += HandleAddClick;
btnRemove.Click += HandleRemoveClick;
}
private void HandleRemoveClick(object _sender, EventArgs _e)
{
m_bindingSource.RemoveCurrent();
}
private void HandleAddClick(object _sender, EventArgs _e)
{
m_bindingSource.Add(new StringValue("Some string"));
}
private void HandleBindingSourceCurrentChanged(object _sender, EventArgs _e)
{
// this line throws an exception when the last item is removed from
// the datagridview
btnRemove.Enabled = (m_bindingSource.Current != null);
}
}
public class StringValue
{
public string Value { get; set; }
public StringValue(string value)
{
Value = value;
}
}
通过纯粹的实验,我发现,如果我不改变按钮状态在CurrentChanged事件处理程序中,然后一切工作正常。所以我怀疑某种操作顺序问题。但是什么?为什么试图与datagridview完全无关的更改会导致问题?
为了使事情更加有趣,如果程序在附带调试器的情况下在VS中启动,则通常无害(或根本不显示)。但如果它自己执行,则会弹出一个消息框,其中包含异常详细信息。
我试着处理datagridview上的RowEnter事件,发现在这种情况下,它仍然认为它有一行并试图从绑定源中检索Current项,但m_bindingSource.Current
已经为null。为什么在处理CurrentChanged事件时这只是一个问题?
任何和所有的帮助将不胜感激。谢谢。
您是否真的验证过它是Button.Enabled和_not_读取BindSource.Current是至关重要的? – 2010-09-10 19:53:26
@亨克:看起来如此。我将Enabled设置代码分成两行:“var currentIsNotNull = m_bindingSource.Current!= null; btnRemove.Enabled = currentIsNotNull;”。然后由btnRemove.Enabled设置器抛出异常。也就是说,如果我根本没有将Enabled属性的值设置在绑定源上,那么一切运行良好,所以也许它是read和Enabled setter的组合。 – 2010-09-10 20:07:37
我试过你的代码,它看起来很完美。没有问题,直接从Visual Studio调试器和.exe没有例外。 ... – pdiddy 2010-09-10 20:22:43