Search code examples
wpfcanvascompositecollection

ListBox on Canvas: overlay multiple canvases or use CompositeCollection?


In wpf with mvvm I use a ListBox with Canvas as ItemsPanelTemplate and DataTemplates to customize appearance.
I would like to improve performance by first adding all items of type 1 to the drawing, then all items of type 2.
I could create two ListBoxes both with Canvas as ItemsPanelTemplate and they would be overlays.
Panning and scrolling could be synchronized by means of bindings.
This way I can raise PropertyChanges for both lists independantly from each other.

Question: do you have experience whether overlaying canvases is good or bad for performance?

I an not sure whether this is also possible using a CompositeCollection for the ItemsSource of one ListBox. Or for that matter give both types a common subclass and stay with ObservableCollection.

Question: do you think that somehow a list with CompositeCollection can be given separate PropertyChanges for different parts of the Collection?

EDIT:
Suppose I have a great number of points, lines, labels for the canvas, each of a different type, however with a common base type. I select the DataTemplate using DataType: DataType="{x:Type my:Point}", DataType="{x:Type my:Line}" etc.
First as quicly as possible I want the user to see the lines. I raise PropertyChanged("Lines") and the ListBox+Canvas for the lines is visible.
In a backgroundworker I raise PropertyChanged("Points") and the ListBox2+Canvas2 for the points is visible.
When done in another backgroundworker I raise PropertyChanged("Labels") and the ListBox3+Canvas3 for the labels is visible.


Solution

  • There's a much simpler solution using basic Object Oriented Programming. Create a base data type and make all of your data objects extend from it. It could be empty, but if nothing else, you could implement INotifyPropertyChanged in it so you don't have to in each of the other data types.

    Then you simply add a property of type ObservableCollection<BaseClass> to your view model or code behind and data bind that to the ListBox.ItemsSource property. As long as you don't set the x:Key values on the different DataTemplates, then WPF will implicitly set them to the relevant data type objects when it renders them.

    So you can put all of your different data types in the same collection. Then you can add your first type in and wait for however long and add some of a different type, or whatever order you feel like.


    UPDATE >>>

    In response to the edit in your question, I don't quite understand the reason for you trying to use the INotifyPropertyChanged interface to show the items, type by type. If you have the base class collection that I mentioned above, then you simply add the instances of the first type to the collection first, so they'll appear first. When you want the next type to appear, just add them into the collection and then they'll appear and so on. The ObservableCollection will take care of that.