EntityViewBase IList.Add throws an exception

Posts   
 
    
yowl
User
Posts: 266
Joined: 11-Feb-2008
# Posted on: 25-Mar-2021 20:06:09   

Llblgen 5.7/Adapter/WPF

Telerik's grid (and maybe others) allow you to intercept the adding of new entities, in Telerik's case this is done by hooking the AddingNewDataItem event. In the handler you can supply the entity you want added with something like this (dummy example as it does nothing worthwhile)

        public void AddingNewDataItem(object sender, GridViewAddingNewEventArgs args)
        {
                args.NewObject = new SomeEntity();
        }

However, this throw the exception with message

Add a new object to the related collection instead, or use IBindingList.AddNew() on this object.

with the stack at SD.LLBLGen.Pro.ORMSupportClasses.EntityViewBase1.System.Collections.IList.Add(Object value) at Telerik.Windows.Data.QueryableCollectionView.AddItemToSourceList(Object newItem, IList sourceList) at Telerik.Windows.Data.QueryableCollectionView.AddItemToSource(Object newItem) at Telerik.Windows.Data.QueryableCollectionView.AddNewInternal(Object newItem) at Telerik.Windows.Data.QueryableCollectionView.AddNew(Object newItem) at Telerik.Windows.Data.QueryableCollectionView.AddNewItem(Object newItem) at Telerik.Windows.Data.DataItemCollection.AddNew(Object newItem) at Telerik.Windows.Controls.GridView.GridViewDataControl.CreateNewItem() at Telerik.Windows.Controls.GridView.GridViewDataControl.ShowInsertRowIfNeeded(Nullable1 position) at Telerik.Windows.Controls.GridView.GridViewDataControl.BeginInsert() at Telerik.Windows.Controls.GridView.GridViewNewRow.HandleUserInteraction() at Telerik.Windows.Controls.GridView.GridViewNewRow.OnMouseLeftButtonDown(MouseButtonEventArgs e)

Sure enough IList.Add implementation is not implemented in EntityViewBase:

        /// <summary>
        /// Not supported. Use AddNew() or add a new object to the related entity collection.
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        int IList.Add( object value )
        {
            if( value == null )
            {
                // design time databinding.
                IEntityCore newEntity = this.AddNew();
                return this.IndexOf((TEntity)newEntity);
            }
            throw new NotSupportedException( "Add a new object to the related collection instead, or use IBindingList.AddNew() on this object." );
        }

How should the EntityCollections be bound to allow this?

Current workaround I have is to use an ObservableCollection<>.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 26-Mar-2021 09:35:59   

As you know which collection is bound, you have to add the new entity to that collection, not return it in the args argument here as it will then call Add() on the bound object (an entity view).

If you need this to keep track of which entities are new, you can also use DataScopes to do this for you. See e.g.: https://www.llblgen.com/Documentation/5.8/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/gencode_datascopes.htm and the example: https://github.com/SolutionsDesign/LLBLGenProExamples_5.x/tree/master/Example_DataScope

Frans Bouma | Lead developer LLBLGen Pro
yowl
User
Posts: 266
Joined: 11-Feb-2008
# Posted on: 26-Mar-2021 20:53:39   

Otis wrote:

As you know which collection is bound, you have to add the new entity to that collection, not return it in the args argument here as it will then call Add() on the bound object (an entity view).

That approach leaves 2 new records in the grid (Can I add pictures here, paste doesn't seem to work?).

Its not for tracking new objects, but for adding existing objects.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 27-Mar-2021 10:33:03   

(Please attach screenshots if you have them)

If you add an existing entity, it still means you have to add it to the bound collection. The collection is bound through an EntityView, so adding a new entity to the collection makes it show up through the view.

Frans Bouma | Lead developer LLBLGen Pro
yowl
User
Posts: 266
Joined: 11-Feb-2008
# Posted on: 27-Mar-2021 16:22:17   

I changed the event to

        void GridViewDataControl_OnAddingNewDataItem(object? sender, GridViewAddingNewEventArgs e)
        {
            TradeEntityCollection.Add(new TradeEntity());
        }

And the result is the attached.

Attachments
Filename File size Added on Approval
addingexistingitem.png 5,887 27-Mar-2021 16:22.33 Approved
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 28-Mar-2021 10:10:19   

I'm not sure what I'm looking at with the screenshot, I see 3 rows but which row is which? Also the event is 'OnAddingNewItem' but you said earlier it's an existing entity that's being added, so not sure when what happens? Keep in mind we don't have the grid control nor know anything about it, so if it's something specific for this grid control we don't have that knowledge.

Frans Bouma | Lead developer LLBLGen Pro
yowl
User
Posts: 266
Joined: 11-Feb-2008
# Posted on: 30-Mar-2021 15:16:28   

Otis wrote:

Keep in mind we don't have the grid control nor know anything about it, so if it's something specific for this grid control we don't have that knowledge.

Ok, that's fine. I don't see how it will work with IBindingList, but I can carry on with ObservableCollection, its not a big deal.

Thanks.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 31-Mar-2021 09:33:52   

If it helps, the example I pointed to works with BindingSources, not sure if you use these too. BindingSource instances can help with binding problems and are a great way to setup binding in design time. I sadly have nothing further to offer as the example works fine so I don't know what it could be that's wrong with the telerik grid situation...

Frans Bouma | Lead developer LLBLGen Pro