0

I have a bit of a weird situation, I've implemented a ObservableConcurrentDictionary (based on the ConcurrentDictionary from .NET), which I used to implement ObservableConcurrentCollection (which just automatically sets the Key property in the Dictionary, and has all the IList, IEnumerable, IQueryable and ICollection methods). This is all working fine when I do something like:

ObservableConcurrentCollection<string> items = new ObservableConcurrentCollection<string>();
dataGrid.ItemsSource = items;
items.Add("TEST");

This is reflected perfectly in the DataGrid.

However, when I do this:

ObservableConcurrentCollection<string> items = new ObservableConcurrentCollection<string>();
items.Add("TEST"); // <-- Notice that this and the line below are swapped.
dataGrid.ItemsSource = items;

It's not working correctly as an item from 'items' suddenly became a KeyValuePair. I can easily fix this by using dataGrid.ItemsSource = items.Values in the last line, but I'd rather have it working just like the previous one (and it's also confusing).

The Cookies Dog
  • 1,915
  • 2
  • 22
  • 38
  • It's really hard to comment on this without seeing your implementation of ObservableConcurrentCollection. But the problem might be on your [Indexer](http://msdn.microsoft.com/en-us/library/6x16t2tx.aspx) – M. Mennan Kara Aug 05 '12 at 18:11
  • There isn't much special about the code really, the ObservableConcurrentDictionary is just a wrapper around the ConcurrentDictionary with a OnCollectionChanged event. The ObservableConcurrentCollection wraps around that with the standard IList stuff (which automatically gets and sets the Key of the ObservableConcurrentDictionary) PLUS IEnumerable and Indexer changed to the values. But the indexer of the ObservableConcurrentCollection isn't even called. – The Cookies Dog Aug 05 '12 at 18:19

3 Answers3

0

Since your new ObservableConcurrentDictionary class is based on ConcurrentDictionary, I suspect the issue is either in the implementation of one of the interface methods.

Without seeing that class, it is hard to diagnose, but I suspect that the problem is in one of the retrieval implementations that is returning the entire dictionary entry rather than the value specified by a key.

For example, when ItemsSource is bound to the grid in the second case, it may retrieve the values through IEnumerable whereas when you call Add in the first case, it is triggering an observable event which contains the correct information.

It should be fairly straightforward to figure out where the problem is occurring by placing a breakpoint in suspect retrieval methods or stepping into the code in the second case as ItemsSource is being asssigned. That should show you fairly quickly which method is being executed and show that the dictionary entry rather than the value is being returned.

competent_tech
  • 44,465
  • 11
  • 90
  • 113
  • I'm pretty sure I've already implemented most methods, couldn't find anything else. I've upload the classes here: http://pastebin.com/TDuTGS1z + http://pastebin.com/Y9bVzNAD – The Cookies Dog Aug 05 '12 at 18:32
  • Based on those classes, it appears that the issue is most likely the IQueryable interface since that is what is used to populate the grid items in the second case. Unfortunately, I don't know nearly enough about linq expressions to provide adequate guidance on how to fix this issue and the MSDN help wasn't too helpful on this interface. – competent_tech Aug 05 '12 at 19:28
  • Yeah, but IQueryable is just the GetEnumerator, which isn't even called in the ObservableConcurrentDictionary, so I doubt that IQueryable is used in the second case. I also tried to override the ToArray method to use type T instead of KeyValuePair but that isn't called either. I'm kinda confused what to do, documentation is pretty bad on MSDN what ItemsSource is exactly doing. – The Cookies Dog Aug 05 '12 at 19:49
  • If you look at ItemsSource in debugger after you set it and expand the Raw portion, you will see the various iqueryable interfaces. It seems somehow that either iqueryable or ienumerable is returning the dictionary entry and not the string value, but I couldn't get it to break in the collection/dictionary methods to tell exactly what is going on. Sorry I can't provide more help on this one. – competent_tech Aug 05 '12 at 19:52
0

for me I always use this

<DataGrid ItemsSource="{Binding}" x:Name="datagrid" >

then

ObservableConcurrentCollection<string> items = new ObservableConcurrentCollection<string>();
items.Add("TEST"); 
dataGrid.DataContext = items;

you can try this, its worknig for me even if i swap my lines

S3ddi9
  • 2,121
  • 2
  • 20
  • 34
0

Solved it by changing the ObservableConcurrentCollection, I removed the inheritance and just created a field for the ObservableConcurrentDictionary. Works like a charm now.

The Cookies Dog
  • 1,915
  • 2
  • 22
  • 38