Question

I want to display a list of self-tracking entities on the form, using standard binding mechanism.

What I want is to select entites from list, change/add or remove them, then either submit changes or reject them depending on user choice.

As far as I understand, for that the list of entities should be attached to the context, then an accept changes call should be made (or not, if the changes are to be rejected). That means that deleted entities must be in the list as well, marked as deleted.

However, they shouldn't be displayed anymore. That means display should be filtered by the state of entities.

Now, usually to do filtering I will wrap my list in BindingList and use the Filter property. From the other hand, entites do not immediately expose their sate (unlike typed data rows) and hold them in ChangeTracker.State. I am at loss, how to do the filtering in this case, especially considering state is an enum, not a plain type.

Was it helpful?

Solution 2

After some deliberation, I found that BindingList does not support filtering, and the same is technically true for BindingSource.

So, with standard filtering out of question, I wrote my own implementation, like this:

private class LivingBindingList : BindingList<Producer>
{
    public LivingBindingList(List<Producer> source)
        : base(source.Where(producer => producer.ChangeTracker.State != ObjectState.Deleted).ToList())
    {
        rem_cache = source.Where(producer => producer.ChangeTracker.State == ObjectState.Deleted).ToList();
    }
    List<Producer> rem_cache;
    protected override void RemoveItem(int index)
    {
        this.Items[index].MarkAsDeleted();
        this.rem_cache.Add(this.Items[index]);
        base.RemoveItem(index);
    }
    protected override void OnAddingNew(AddingNewEventArgs e)
    {
        e.NewObject = new Producer()
        {
            NameProducer = "Новый производитель",
            GUID = Guid.NewGuid(),
            Type = 1,
            Note = String.Empty
        };
        base.OnAddingNew(e);
    }
    internal IEnumerable<Producer> GetAllForSubmit()
    {
        return this.Items.Concat(rem_cache);
    }
}

With this, I can bind to the list, add and delete as much as I want, and ofr commit purposes retrieve all records, including dead ones, with GetAllForSubmit().

OTHER TIPS

[Edit : removed first solution consisting in deleting entities from list]

You may add a IsDeleted Property to your entities

public bool IsDeleted
{ 
    get {
        return ChangeTracker.State == ObjectState.Deleted
    } 
}

and filter on that property. STE are partial classes and may be extended

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top