0

The main reason I started with WPF in the first place was the promise of all the awesome possibilities of databinding. After days of headaches I'm beginning to think that one of the most common scenarios is impossible, and I'd love to be proved wrong! :)

  • I have a ListBox that will have instances of my custom class as its ListItems.
  • My class is DataBinding-ready by implementing some DependencyProperties.
  • My ListBox has a custom DataTemplate to display these properties in a nice layout.
  • ListBox has the ItemsSource set to an ObservableCollection<MyClass>
  • The listbox may need to display hundreds, even thousands of items so in order to maintain a responsive UI, they need to be instantiated in the background.

Turns out it's impossible to create instances of my class in a background thread and add them to the ObservableCollection (or directly to the listbox, when we omit the ItemsSource) in the UI thread, as long as they are DependencyObjects. It throws an exception saying

Must create DependencySource on same Thread as the DependencyObject

How am I supposed to handle a scenario like this in WPF? Don't use DPs at all and go with INotifyPropertyChanged? What people actually do, when they need to do this? I think this is a fairly common scenario and I'm quite upset how most DataBinding related articles ramble about the possibility to change a TextBox background color if you type in "Magenta"... :)

Kjuly
  • 34,476
  • 22
  • 104
  • 118
oli.G
  • 1,300
  • 2
  • 18
  • 24
  • Could you show some code? Perhaps your constructor is trying to do too much (to need to be done in the background...) – J... Oct 14 '12 at 11:53
  • You could use `Dispatcher.Invoke`? – Patrick Oct 14 '12 at 12:03
  • possible duplicate of [Asynchronously adding to ObservableCollection (or an alternative)](http://stackoverflow.com/questions/12881489/asynchronously-adding-to-observablecollection-or-an-alternative) – Patrick Oct 14 '12 at 12:11
  • @Patrick I believe (I hope) it's not a duplicate - both questions come from the same problem but I'm asking for a different kind of answer (at least that was the intention)... :) This one is "how do hell do you implement this scenario in WPF" and the one you posted here is "how can I make my solution work" – oli.G Oct 14 '12 at 12:19
  • @J... The only thing the class (and its constructor) really does is store two strings without any computations - a filename and a path to the thumbnail. I doubt the problem's there – oli.G Oct 14 '12 at 12:21
  • @oli.G - no, the problem is that you're creating them in a separate thread. I was just trying to figure out what might have been so intensive that they needed to be created in a separate thread. I also usually use INotifyPropertyChanged for this sort of thing, but using DPs with modest constructors you can still invoke the creation on the UI without hanging anything as long as you don't try to do them all at once in one method. – J... Oct 14 '12 at 15:29

2 Answers2

1

I would only ever implement Dependency Properties when I am implementing or extending a control. All of the data that is bound in I would simply use INotifyPropertychanged. Have a look at Josh Smith's MVVM pattern article, this is what clarified a lot of this for me.

Also, in moving towards a more asynchronous pattern, these days I use ReactiveUI as it incorporates a lot of the asynchronous commands in patterns too.

AlSki
  • 6,868
  • 1
  • 26
  • 39
1

You can use INotifyPropertyChanged instead (as I have recommended), or you could make your objects Freezable and freeze them after creation, or you could break down the creation of your objects into distinct steps or groups and do each step in a separate dispatcher message. For example, create your objects in groups of 10 and do each in its own, lower priority dispatcher message.

Kent Boogaart
  • 175,602
  • 35
  • 392
  • 393