0

There are a lot of questions on here about updating controls(mainly the ObservableCollection) using a background worker thread. I am trying to implement this solution. However, my situation has just a little bit more depth to it because it calls to a function in the add method that returns the object to be added.

This is what my solution looks like right now (note that my ObservableCollection is bound to a TreeView control):

//Pass from Background Thread
MainTreeViewModel.AddLocation(locationName, locationValue);

//UI Thread (MainTreeViewModel)
public void AddLocation(MultiItemString displayName, int locationValue)
{
    var node = Data.GetAllChildren(x => x.Children).Distinct().ToList().First(x => x.identify == 'P'); //Location Parent

    App.Current.Dispatcher.BeginInvoke((Action)delegate()
    {
        node.Children.Add(CreateLocationNode(displayName, locationValue));
    });
}

CreateLocationNode:

//Also location in MainTreeViewModel
private HierarchicalVM CreateLocationNode(MultiItemString displayName, int locationValue)
{
    MultiItemString locationNumber = new MultiItemString(new[] {locationValue.ToString() + " "}, false);

    var newLocationNode = new HierarchicalVM()
    {
        DisplayName = displayName, //Examples of props that turn out as NULL
        LocationNumber = locationNumber,
        TreeView_LocValue = locationValue,
        Children = new ObservableCollection<HierarchicalVM>(), //This is what is being added to
        Commands = 
    };

        return newLocationNode;
}

When doing this I find that an object gets added, but all of the properties attached to it receive null values. Oppositely, when I am doing everything in the UI thread and just using node.Children.Add(CreateLocationNode(displayName, locationValue));, everything attaches how it should. Why am I getting a different result here, and how can I fix it?

Please let me know if you need more code.

Community
  • 1
  • 1
Eric after dark
  • 1,768
  • 4
  • 31
  • 79
  • You should post a more complete code example. But my first thought is, are you sure that App.Current.Dispatcher gives you the right Dispatcher? Presumably the code involves some WPF control or framework element...what happens if you use that object's Dispatcher property to invoke the Action instead of using App.Current.Dispatcher? – Peter Duniho Oct 17 '14 at 18:53
  • @PeterDuniho I've added the code for the function that returns the collection object to be added. I was under the impression that `App.Current.Dispatcher` gave me the dispatcher for the UI Thread. The collection is part of a `TreeView`. So with that, I should try the `TreeView's` dispatcher property? – Eric after dark Oct 17 '14 at 19:02
  • @Clemens I didn't try that, but as you should see now in my updated code, I do pass parameters to the function that the `.Add()` line of code is in. – Eric after dark Oct 17 '14 at 19:07
  • @Ericafterdark: I would've thought that would give you the UI thread Dispatcher too. But I don't know for sure that it does (relatively new to WPF myself). That said, looking at the additional code you posted, I just don't see how unbound properties assigned on construction could wind up getting set back to null. On the other hand, since they are properties, you can set a break-point on the setter and see what's setting them back to null. Finally, the code you posted doesn't look quite genuine: there's undeclared "node" and "locationNumber" variables, and "locationToCopy" seems unused. – Peter Duniho Oct 17 '14 at 19:14
  • @PeterDuniho Okay, I will set a break point in the setter and see what I can get out of it. Sorry about the code. Sometimes that happens in my attempt to only add relevant code that other people will understand. I have declared node, and Location Number, and I have gotten rid of locationToCopy because it is not really involved in the question. – Eric after dark Oct 17 '14 at 19:19
  • @Ericafterdark: great, let us know what you find. By the way, I just checked and it does look like, at least for a simple WPF app, App.Current.Dispatcher is the same Dispatcher object as the one that owns the GUI objects. So you should be fine on that front. – Peter Duniho Oct 17 '14 at 19:24
  • @PeterDuniho Okay cool, so I am all clear to use `App.Current.Dispatcher`. Now through debugging I am finding that the collection item does not add to the collection at all like this. `node.Children.Count() = 0`. It goes into `CreateLocationNode` and only gets as far as `locationNumber` until it skips out of it and goes back to the background thread. – Eric after dark Oct 17 '14 at 19:40
  • That may be a debugger artifact. What VS version are you using? The non-Express versions allow you to suspend a thread (e.g. your background thread) so that as you single-step through the program, you don't keep getting switched from one to the other. If it's not the debugger pulling you away, then maybe you're actually getting an exception thrown. If you are blindly catching all exceptions somewhere, you might not notice that. In any case, since the code in your question is obviously not the actual code, it's hard to comment on what might be going on. – Peter Duniho Oct 17 '14 at 20:04
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/63253/discussion-between-eric-after-dark-and-peter-duniho). – Eric after dark Oct 17 '14 at 20:04

0 Answers0