Freezing a listboxitem while items are being added
We have a ListBox that has a number of items. Items are inserted into the ListBox via an ObservableCollection. Some of these items can be edited right in the ListBox. However, if an item is added at an index < the edited item's index, the entire content of the ListBox开发者_运维问答 moves down.
What we'd like to do is the following: if an item is in edit mode, we'd like to freeze its position on the screen. It is fine if items are added to the collection and the UI around the item changes. But the position of the item should remain constant on the screen.
The only thing I've been able to do so far is attach to the ScrollChanged event and, at most, use either BringIntoView or ScrollIntoView methods to ensure that the item is always displayed somewhere in the UI, but I am unable to lock down its position.
Has anyone done something like this and help out?
I think the following would solve your problem:
When entering edit mode, keep a reference to the object you're editing, its index in listbox and the ScrollViewer's HorizontalOffset.
In a handler to the ObservableCollection.CollectionChanged event find the new index of the object you editing, if the index changed, swap the edited item with the one now taking it's place (or some other logic if you want to keep a certain order). Then if the ScrollViewer.HorizontalOffset changed, move it back to the said offset.
This will make sure the item you're editing will always stay in the exact same place in the list and in the UI.
Hope this help you out.
You could always force items to be added to the end of your collection. Otherwise, I think you are on the right track with scrolling the ScrollViewer. When entering 'edit mode', track the current horizontal offset.
ScrollViewer sv = listBox.GetScrollViewer();
double indexPos = sv.HorizontalOffset;
However, I think you would be better off attaching to the ObservableCollection.CollectionChanged event. When the event fires, check if the new value was inserted above your 'edit mode' item. If it is, then run the following code.
ScrollViewer sv = listBox.GetScrollViewer();
sv.ScrollToHorizontalOffset(indexPos+1); // This will obviously require an offset
Is the problem that you simply don't want it moving? Or is the problem that you have referenced said item by its index number and the change in index causes other problems when you apply the changes (like applying them to the item that is now at the previous index)?
If the problem is that a change of index causes problems in code, then I would stop using the index and instead get a reference to the object. Later you can always get the index of the item if you find you need it.
Would it be feasible to switch to a ListView, and use EnsureVisible?
If freezing the rest of the listbox is a viable option. Such that items which are added don't appear until after the edit has been completed or escaped then you could try using BeginUpdate
and EndUpdate
to stop the ListBox from being repainted. I'm not sure how that would effect your editing process though.
精彩评论