Csharp/C#教程:DataGridView绑定问题:“索引-1没有值。”分享


DataGridView绑定问题:“索引-1没有值。”

我有一个datagridview绑定到绑定源和窗体上的几个按钮。 一个按钮将一个项目添加到绑定源,另一个按钮删除当前选定的项目。 还有一个事件处理程序,它侦听CurrentChanged事件并更新“删除”按钮的“已启用”状态。

在我从datagridview中删除最后一项之前,所有东西都是笨拙的。 然后我看到一个非常丑陋的例外:

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)rn 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(); 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中启动程序且附加了调试器,则exception通常是无害的(或根本不显示)。 但如果它自己执行,会弹出一个带有exception详细信息的消息框。

我已经尝试在datagridview上处理RowEnter事件,并发现在这种情况下,它仍然认为它有一行并尝试从绑定源中检索Current项,但m_bindingSource.Current已经为null。 为什么在处理CurrentChanged事件时这只是一个问题?

任何和所有的帮助将不胜感激。 谢谢。

也许不是一个真正的答案,但我记得BindingSource和Datagrid在这个部门是挑剔和脆弱的。 我的一般建议是不要使用RemoveCurrent,而是从基础数据存储中删除记录。

经过一番讽刺后,我发现了一些好消息和一些坏消息:

好消息是(m_bindingSource.Current != null); 部分不是问题。 运行得很好。

坏消息是错误是由btnRemove.Enabled = false;引起的btnRemove.Enabled = false;

看看我的意思,改变: btnRemove.Enabled = (m_bindingSource.Current != null); 至:

 btnRemove.Enabled = false; if(m_bindingSource.Current != null) btnRemove.Enabled = true; 

代码将在第一行死亡。

我不是百分百肯定为什么,但如果你移动btnRemove.Enabled = false直到HandleRemoveClick方法的第一行,一切都按计划进行。

希望对你有所帮助。

我今天遇到了同样的问题,并在此主题中找到了解决方法。 不幸的是,我不喜欢拆分按钮的启用/禁用代码。 所以我做了一些研究,找到了另一个解决方案,对我有用。

我所做的就是解决IndexOutOfRangeException是在设置按钮的启用/禁用之前重置绑定。 (为了优化性能,您可以检查数据源计数是零还是货币管理器的位置是-1。在其他情况下,不需要重置。)

 private void HandleBindingSourceCurrentChanged(object _sender, EventArgs _e) { if(m_bindingSource.Count == 0) // You also can check position == -1 { m_bindingSource.ResetBindings(false); } btnRemove.Enabled = (m_bindingSource.Current != null); } 

希望这很有帮助。

我最终像这样解决它:

 private void HandleRemoveClick(object _sender, EventArgs _e) { btnRemove.Enabled = false; m_bindingSource.RemoveCurrent(); } private void HandleBindingSourceCurrentChanged(object _sender, EventArgs _e) { if(m_bindingSource.Current != null) btnRemove.Enabled = true; } 

这有点奇怪,但似乎工作正常。

尝试用以下内容替换CurrentChanged处理程序:

 private void HandleBindingSourceCurrentChanged(object _sender, EventArgs _e) { if (m_bindingSource.Position < 0) return; btnRemove.Enabled = (m_bindingSource.Current != null); } 

我认为问题出现是因为您正在禁用当前具有焦点的按钮。 禁用聚焦控制应该没有错,但在某些情况下会产生所描述的问题。 如果您首先将焦点设置为其他控件,我认为您会看到问题消失。 我遇到了同样的问题,它对我有用。

上述就是C#学习教程:DataGridView绑定问题:“索引-1没有值。”分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注---计算机技术网(www.ctvol.com)!

  Dim bCurrent As Boolean = CredentialTypeBindingSource.Current IsNot Nothing 'set focus to the New button which is never disabled NewBtn.Focus() 'enable/disable the other buttons EditBtn.Enabled = bCurrent DeleteBtn.Enabled = bCurrent 

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/cdevelopment/951678.html

(0)
上一篇 2021年11月18日
下一篇 2021年11月18日

精彩推荐