This is a migrated thread and some comments may be shown as answers.

add new record - Index was out of range.

10 Answers 199 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Travis
Top achievements
Rank 1
Travis asked on 03 Nov 2008, 05:23 AM

Version: Q2 2008 SP1- Released:9/10/2008 - WPF/VS2008-SP1

 

We're able to edit an existing record, but couldn't successfully include a record into the GridView. Our data is stored in a List<T> which is used to commit each record to the backend.

 

Pressing the INSERT key on the GridView will call the 'AddingNewDataItem' method.  When the cursor leaves the edited row, the 'EditEnded' method is called.  When this method executes to the end, an error occurs:

 

ERROR: Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index

STACK TRACE: at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource)
   at System.ThrowHelper.ThrowArgumentOutOfRangeException()
   at System.Collections.Generic.List`1.get_Item(Int32 index)
   at Telerik.Windows.Data.Grouping.DataRecordStore`1.GetDataRecord(Int32 index)
   at Telerik.Windows.Data.Grouping.ListOfRecordsExtensions.InsertIndex[TElement](IList`1 recordList, Int32 insertionIndex, Int32 dataSourceIndex, DataRecordStore`1 recordStore)
   at Telerik.Windows.Data.RecordTreeBuilder`1.InsertRecordInGroup(IList`1 dataRecordList, TElement dataItem, Int32 index)
   at Telerik.Windows.Data.RecordTreeBuilder`1.AddExistingDataRecord(IList`1 targetCollection, TElement dataItem, Int32 index)
   at Telerik.Windows.Data.RecordTreeBuilder`1.AddNewDataRecord(IList`1 targetCollection, TElement dataItem, Int32 index)
   at Telerik.Windows.Data.RecordTreeBuilder`1.AddNewRecord(IList`1 targetCollection, Object recordItem, Int32 index)
   at Telerik.Windows.Data.RecordManager.AddNewRecord(Object recordItem, Int32 index, String fieldName)
   at Telerik.Windows.Controls.GridView.GridViewRow.UpdateDataRecords(DataRecord changedRecord, String changedFieldName, RecordsChangeListener changeListener)
   at Telerik.Windows.Controls.GridView.GridViewRow.HandleValueChangedWithoutNotifications(DataRecord changedRecord, String changedFieldName, RecordsChangeListener changeListener)
   at Telerik.Windows.Controls.GridView.GridViewRow.HandleValueChangedAfterEdit(FieldRoutedEventArgs editEventArgs, RecordsChangeListener changeListener)
   at Telerik.Windows.Controls.GridView.GridViewRow.Cell_EditCommitted(Object sender, FieldRoutedEventArgs e)
   at Telerik.Windows.Controls.GridView.GridViewRow.CommitEdit()
   at Telerik.Windows.Controls.GridView.GridViewCell.CommitEditedRow()
   at Telerik.Windows.Controls.GridView.GridViewCell.TryCommitPreviousEdit()
   at Telerik.Windows.Controls.GridView.GridViewCell.HandleLostFocus()
   at Telerik.Windows.Controls.GridView.GridViewCell.OnGotFocus(RoutedEventArgs e)
   at System.Windows.UIElement.IsFocused_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
   at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
   at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
   at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
   at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, OperationType operationType)
   at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, OperationType operationType, Boolean isInternal)
   at System.Windows.DependencyObject.SetValue(DependencyPropertyKey key, Object value)
   at System.Windows.Input.FocusManager.OnFocusedElementChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
   at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
   at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
   at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
   at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, OperationType operationType)
   at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, OperationType operationType, Boolean isInternal)
   at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
   at System.Windows.Input.FocusManager.SetFocusedElement(DependencyObject element, IInputElement value)
   at System.Windows.Input.KeyboardNavigation.UpdateFocusedElement(DependencyObject focusTarget)
   at System.Windows.FrameworkElement.OnGotKeyboardFocus(Object sender, KeyboardFocusChangedEventArgs e)
   at System.Windows.Input.KeyboardFocusChangedEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
   at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
   at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
   at System.Windows.Input.InputManager.ProcessStagingArea()
   at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
   at System.Windows.Input.KeyboardDevice.ChangeFocus(DependencyObject focus, Int32 timestamp)
   at System.Windows.Input.KeyboardDevice.TryChangeFocus(DependencyObject newFocus, IKeyboardInputProvider keyboardInputProvider, Boolean askOld, Boolean askNew, Boolean forceToNullIfFailed)
   at System.Windows.Input.KeyboardDevice.Focus(DependencyObject focus, Boolean askOld, Boolean askNew)
   at System.Windows.Input.KeyboardDevice.Focus(IInputElement element)
   at System.Windows.Input.Keyboard.Focus(IInputElement element)
   at Telerik.Windows.Controls.GridView.GridViewCell.OnMouseLeftButtonDown(MouseButtonEventArgs e)
   at System.Windows.UIElement.OnMouseLeftButtonDownThunk(Object sender, MouseButtonEventArgs e)
   at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
   at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent)
   at System.Windows.UIElement.CrackMouseButtonEventAndReRaiseEvent(DependencyObject sender, MouseButtonEventArgs e)
   at System.Windows.UIElement.OnMouseDownThunk(Object sender, MouseButtonEventArgs e)
   at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
   at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
   at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
   at System.Windows.Input.InputManager.ProcessStagingArea()
   at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
   at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
   at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
   at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Boolean isSingleParameter)
   at System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority priority, Delegate method, Object arg)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.Run()
   at System.Windows.Application.RunDispatcher(Object ignore)
   at System.Windows.Application.RunInternal(Window window)
   at System.Windows.Application.Run(Window window)
   at System.Windows.Application.Run()

 

Record editing is working, but crashes when committing a new record.  Secondly, is it possible to call the 'AddingNewDataItem' method rather than wait for the user to press the INSERT key?

 

-Trav.

10 Answers, 1 is accepted

Sort by
0
Atanas
Telerik team
answered on 06 Nov 2008, 06:29 AM
Hello Travis,

We will be releasing a new version of our controls by the end of this week and this issue will be addressed in the latest release.

Sincerely yours,
Atanas
the Telerik team

Check out Telerik Trainer, the state of the art learning tool for Telerik products.
0
Travis
Top achievements
Rank 1
answered on 11 Nov 2008, 04:41 AM

I've installed the Q3 release, but this codebase does not execute the 'AddingNewDataItem' event?

0
Travis
Top achievements
Rank 1
answered on 11 Nov 2008, 05:42 AM
'AddingNewDataItem' event will not fire on BindingList<T>, but does fire on List<T>.

The initial problem (add new record) still exists in the Q3 release.
0
Pavel Pavlov
Telerik team
answered on 12 Nov 2008, 04:56 PM
Hello Travis,

We reproduced the problem. It happens when you handle only the AddingNewDataItem event to create a new data object. RadGridView does not know how to add that object to the underlying data source and assumes that either your client code or the data source collection will do it. The correct place to do that is to handle the GridViewCell.EditEnded event and add the newly-added object to your List<T> data source. I am attaching a sample project that has been adapted from our example here. The sample uses a generic list instead of an ADO.NET DataTable.

The AddingNewDataItem event will only fire if you are binding to a "simple" collection like a generic list or a plain IEnumerable. When you bind to advanced collections like binding lists, you will not get that event simply because a binding list knows how to construct a new object.

As far as programmatically showing the insert new object UI in the grid, at the moment we do not have public API exposed for that. You can still do it by simulating an Insert key down event like this:

private void PressInsertKeyOnRadGridView()  
{  
    var itemsControl = this.RadGridView1.ItemsControl;  
    itemsControl.Focus();  
 
    // Simulate INSERT key is pressed from Framework  
    var keyEventArgs = new KeyEventArgs(Keyboard.PrimaryDevice, Keyboard.PrimaryDevice.ActiveSource, 0, Key.Insert);  
    keyEventArgs.RoutedEvent = UIElement.KeyDownEvent;  
    InputManager.Current.ProcessInput(keyEventArgs);  


The attached sample project calls that method when you click the button.

Best wishes,
Pavel Pavlov
the Telerik team

Check out Telerik Trainer, the state of the art learning tool for Telerik products.
0
Travis
Top achievements
Rank 1
answered on 13 Nov 2008, 12:55 AM

I’ve reviewed the attached sample and this works as expected – thanks Pavel.  However, is it possible to perform a rollback from within the ‘EditEnded’ event?

-Trav.

0
Pavel Pavlov
Telerik team
answered on 13 Nov 2008, 02:58 PM
Hello Travis,

What do you mean by 'rollback'?

Are you trying to implement some kind of input validation?
If so, please take a look at the example here. Click on the C# tab to see details on how validation should be implemented.

Best wishes,
Pavel Pavlov
the Telerik team

Check out Telerik Trainer, the state of the art learning tool for Telerik products.
0
Travis
Top achievements
Rank 1
answered on 14 Nov 2008, 05:33 AM

When adding an inline record, the new record would be saved into the database from within the ‘EditEnded’ event.  If this process fails, I would also like to cancel the record changes in the grid. I have included sample code to explain the situation:-

 

private void radReferenceList_EditEnded(object sender, RecordRoutedEventArgs e)

{

   var mySelectedRecord = e.Record as DataRecord;

   var myCreditOfficer = mySelectedRecord.Data as Entities.CreditOfficer;

   var mySelectedGrid = (RadGridView)sender;

 

   try

   {

       if (mySelectedRecord.IsDisconnected)

       {   // Add operation

           CreateCreditOfficerInDatabase(myCreditOfficer);

 

           var myCreditOfficers =
               (IList<Entities.CreditOfficer>)mySelectedGrid.ItemsSource;

 

 

           myCreditOfficers.Add(myCreditOfficer);

       }

       else

       {   // Update operation

           UpdateCreditOfficerInDatabase(myCreditOfficer);

      }

   }

   catch (Exception ex)

   {

// If an error occurs; the record is not committed to the database.

// This item would not be added into List<T>, and so Telerik control will crash!

//   - Exception has been thrown by the target of an invocation.

//

// We need to perform a ‘Record.CancelUpdate()’ here. Is this possible?

   }

}

 

 

 

 

 

0
Hristo Deshev
Telerik team
answered on 17 Nov 2008, 12:49 PM
Hello Travis,

I just thought of a way to "rollback" your visual changes. I am using the fact that the event args will have an OldValue property that you can use to update your object back to its original state. To be able to do that in a generic way that works for various objects, you can use the System.ComponentModel property descriptors. Here's the code:

//determine if we should rollback the visual edit (DB error) 
var shouldRollBack = true
if (shouldRollBack) 
    var editedPerson = (Person) cell.DataContext; 
    var editedProperty = TypeDescriptor.GetProperties(editedPerson)[cell.DataColumn.DataMemberPath]; 
    editedProperty.SetValue(editedPerson, e.OldValue); 

I think you can easily substitute the Person type with your own Entities.CreditOfficer type.

I am attaching the modified project for your reference.

Sincerely yours,
Hristo Deshev
the Telerik team

Check out Telerik Trainer, the state of the art learning tool for Telerik products.
0
Travis
Top achievements
Rank 1
answered on 18 Nov 2008, 01:59 AM
Hi Hristo,

Your example does not rollback a newly added record.

-Trav.
0
Hristo Deshev
Telerik team
answered on 20 Nov 2008, 04:51 PM
Hi Travis,

I managed to get rollback for adding a new record working too. It required some hacks, like removing the data item from the collection and rebinding the grid so that we get rid of the obsolete row. I have tried to hide the ugly code behind a class, UndoHelper that will require you to pass as a generic parameter your data item type (Person in my example), and notify it whenever an event of interest happens: creating a new data item, ending an edit, undoing an edit.

I am attaching the modified project.

Kind regards,
Hristo Deshev
the Telerik team

Check out Telerik Trainer, the state of the art learning tool for Telerik products.
Tags
GridView
Asked by
Travis
Top achievements
Rank 1
Answers by
Atanas
Telerik team
Travis
Top achievements
Rank 1
Pavel Pavlov
Telerik team
Hristo Deshev
Telerik team
Share this question
or