2011-10-18 33 views
3

私はWindowsフォーム上にデータグリッドを持っています。セルがクリックされると、DataGridがCurrencyManagerからIndexOutOfRangeExceptionをスローします

グリッドを最初に更新してデータを格納し、それをクリックすると、以下の例外が発生します。

例外的に、フォームのウィンドウ処理では例外が深く、 なので、フォームを起動する時点で例外がキャッチされます。

コールスタックの下にコールスタックを表示するには、「外部コードを表示」にチェックを入れてください。そうでない場合は[外部コード]と表示されます。

選択したアイテムと次に選択されたアイテムのために発生したメッセージが原因で起こった可能性があると思っている就労/トラブルシューティングの手順については、DataGridView.SelectAll();を更新してみましたデータ、これは同じ結果を持っていました。

例外:

IndexOutOfRangeException 
{"Index -1 does not have a value."} 

コールスタック:

System.Windows.Forms.dll!System.Windows.Forms.CurrencyManager.this[int].get(int index) + 0xa1 bytes 
System.Windows.Forms.dll!System.Windows.Forms.CurrencyManager.Current.get() + 0x16 bytes  
System.Windows.Forms.dll!System.Windows.Forms.DataGridView.DataGridViewDataConnection.OnRowEnter(System.Windows.Forms.DataGridViewCellEventArgs e) + 0x101 bytes  
System.Windows.Forms.dll!System.Windows.Forms.DataGridView.OnRowEnter(ref System.Windows.Forms.DataGridViewCell dataGridViewCell = null, int columnIndex = 1, int rowIndex = 0, bool canCreateNewRow, bool validationFailureOccurred) + 0x218 bytes 
System.Windows.Forms.dll!System.Windows.Forms.DataGridView.SetCurrentCellAddressCore(int columnIndex = 1, int rowIndex = 0, bool setAnchorCellAddress, bool validateCurrentCell, bool throughMouseClick = true) + 0x59f bytes 
System.Windows.Forms.dll!System.Windows.Forms.DataGridView.OnCellMouseDown(System.Windows.Forms.DataGridView.HitTestInfo hti, bool isShiftDown, bool isControlDown) + 0x12db bytes 
System.Windows.Forms.dll!System.Windows.Forms.DataGridView.OnCellMouseDown(System.Windows.Forms.DataGridViewCellMouseEventArgs e) + 0x318 bytes 
System.Windows.Forms.dll!System.Windows.Forms.DataGridView.OnMouseDown(System.Windows.Forms.MouseEventArgs e) + 0x153 bytes 
System.Windows.Forms.dll!System.Windows.Forms.Control.WmMouseDown(ref System.Windows.Forms.Message m, System.Windows.Forms.MouseButtons button, int clicks) + 0xcf bytes  
System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m) + 0x86e bytes 
System.Windows.Forms.dll!System.Windows.Forms.DataGridView.WndProc(ref System.Windows.Forms.Message m) + 0x92 bytes 
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.OnMessage(ref System.Windows.Forms.Message m) + 0x10 bytes  
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref System.Windows.Forms.Message m) + 0x31 bytes 
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd, int msg = 513, System.IntPtr wparam, System.IntPtr lparam) + 0x57 bytes 
[Native to Managed Transition] 
[Managed to Native Transition] 
System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(int dwComponentID, int reason = 4, int pvLoopData = 0) + 0x24e bytes 
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason = 4, System.Windows.Forms.ApplicationContext context = {System.Windows.Forms.Application.ModalApplicationContext}) + 0x177 bytes 
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) + 0x61 bytes  
System.Windows.Forms.dll!System.Windows.Forms.Application.RunDialog(System.Windows.Forms.Form form) + 0x33 bytes  
System.Windows.Forms.dll!System.Windows.Forms.Form.ShowDialog(System.Windows.Forms.IWin32Window owner) + 0x373 bytes  

答えて

5

問題は、最終的には、データ・ソースではなく、一般的なListとしてジェネリックBindingListを使用することによって解決しました。

フォームとのユーザーのやりとりに反応してデータソースの値を変更する必要があったため、変更するたびにリストを再作成していました(List<>の場合)。

リスト内のオブジェクトにINotifyPropertyChangedを実装した後、BindingList<>を使用してデータを一度バインドし、必要に応じて更新しました。

なぜこのリストを使用して問題が発生したのか分かりませんが、私は実行可能な解決策があることを嬉しく思っています。

+0

おそらく 'CurrencyManager'は元のリストへの参照を持っていました。そして 'DataGridView'の' DataSource'が更新されたとき、 'CurrencyManager'はまだ古いバージョンのリストを持っていましたか? –

1

あなたはコード内のクリックイベントを処理した場合には、背後の前に任意のタスクを実行する適切な検証を行います。

if (e.ColumnIndex == 1) // check for correct column 
{ 
    if (e.RowIndex >= 0) // check for valied row index 
    { 
     DataGridViewRow dataGridViewRow = dataGridView1.Rows[e.RowIndex]; 
     // do stuff like update delete.. 
    } 
} 
+1

DevExpressでは、CurrencyManagerエラーがほとんど明示的ではありません... – Seb

+0

乾杯DSWと非常によくSebを置く - それは私が書いたコードからスローされていない、スタック全体がシーンコードの背後にあります。 –

0

古いリストをどこかに保存して、新しいオブジェクトのために何かを更新しようとしているようです。

// Get old list 
List<BoardRow> rows = (List<BoardRow>)rowsDataGridView.DataSource; 

// Add new row 
rows.Add(form.boardRow); 

// Re-create list 
List<BoardRow> rowsNew = new List<BoardRow>(rows.Count); 
rowsNew.AddRange(rows); 

// Rebind source 
this.rowsDataGridView.DataSource = rowsNew; 

非常に効果的ではないが、あなたは小さなデータセットのために汚いハックが必要な場合は、まだ動作します: あなたはこのように、リストを再作成することによって、これをバイパスすることができます。

関連する問題