ListBox Databinding (Hell)

ListBox Databinding (Hell)

Old forum URL: forums.lhotka.net/forums/t/6471.aspx


xAvailx posted on Friday, February 20, 2009

Winforms > ListBox > Csla 3.6

I somehow got suckered into trying databinding again for a project...and I am having some issues with a bound listbox. I am binding an editable child collection to a listbox. The listbox is selectionmode is "MultipleExtended". The user can select the rows and then click on a "remove" button. The intended functionality is to remove from the childcollection all the items that were selected. And here is where my problem lies...I have loop that goes thru the selected items, but after I remove one item from the child collection, my listbox selected items change (not all the items originally selected are in there). This is what my code looks like. Any help is appreciated...

Edit: One more note, I think that what is happening is after the first remove happens, the next item on the list becomes "selected".

For index As Integer = Me.RolesListbox.Items.Count - 1 To 0 Step -1

If (Me.RolesListbox.GetSelected(index)) Then

Dim role As UserRole = CType(Me.RolesListbox.Items(index), UserRole)

If (mUser.Roles.Contains(role.RoleId)) Then

mUser.Roles.Remove(role.RoleId)

End If

End If

Next

tetranz replied on Friday, February 20, 2009

I think the listbox is receiving databinding events and getting confused as you're removing items from the collection. I think you're going through the selections in reverse in an attempt to avoid that but even so ... I think I would separate things by reading the selection from the listbox into a "List to Remove" first and then forget about the listbox while you use that list to remove items from the collection. Then you probably want to do a bindingSource.ResetBindings to update the listbox with what's left. It might go more smoothly too if you set RaiseListChangedEvents = false on the child binding list while you remove.

You may have edit level stuff to deal with although maybe not since a listbox is essentially a read-only thing. The ultimate foolproof way is probably to grab the list to remove, unbind everything like we have to do while saving, do the removes and rebind.

xAvailx replied on Friday, February 20, 2009

Thanks for the response tetranz.


I changed the code to (see below), but now when I save my editlevels are out of whack. When I tyr saving it throw the edit level exception.


Any hints on how to fix? I guess I need to understand better what magic databinding is doing to my BO's, but until my new book arrives for now I am trying to get by.


 


RolesBindingSource.RaiseListChangedEvents = False


For index As Integer = Me.RolesListbox.Items.Count - 1 To 0 Step -1


If (Me.RolesListbox.GetSelected(index)) Then


Dim role As UserRole = CType(Me.RolesListbox.Items(index), UserRole)


If (mUser.Roles.Contains(role.RoleId)) Then


mUser.Roles.Remove(role.RoleId)


End If


End If


Next


RolesBindingSource.RaiseListChangedEvents = True


RolesBindingSource.ResetBindings(False)

tetranz replied on Friday, February 20, 2009

Sorry, I don't really have any bright ideas except, as I suggested before. I would loop through the listbox first, not removing items but building an independent list of the items (or their ids) that the user has selected for removal. i.e, a snapshot of the user's selection. Then loop around that list to do the actual removes rather than looping around the listbox. I think some of the problem is that the listbox is "moving under your feet" as you remove items from the collection. When you remove an item, the listbox will received a ListChanged event and who knows what that does to it's multiple selections.

But, now that you're having edit level issues I think the safest thing might be to unbind everything before doing the removes. The easiest way to see how to do that is look at the ProjectTracker sample project and see how Rocky applies the edits and unbinds before saving. I know your problem is not related to saving but I think it is somewhat unusual to have a list box bound to an editable collection. I'm not saying it's wrong but maybe not common. I'd be tempted to use a one column grid on an editable collection.

tetranz replied on Saturday, February 21, 2009

I misread this last night. I missed the fact that the edit level problems occur when you save, not when removing the child items. In that case it sounds like the usual binding issues lots of people have had. You need to follow the Project Tracker example of how to unbind root and children before saving. It sounds like disabling those events fixed the remove process.

xAvailx replied on Monday, February 23, 2009

Thanks for the help, I think got it fixed. I think the datasource was bound to the wrong place. I had it bound directly to the child collection instead of the parent's child property. As far as my scenario, it basically resembles Window's user account management. We have user screen with a roles listbox on a tab. The actor can remove roles from the listbox, or click and add button that brings up the roles windows. Shouldn't be something out of the ordinary. Either way, thanks for the help.

Copyright (c) Marimer LLC