Adding Tubes to the Flights Demo programmatically (4 days on this is too long...)

Jul 18, 2014 at 3:06 AM
Edited Jul 18, 2014 at 5:11 PM
Experts,

This is just getting to the point where it is dragging me down mentally. I hate being stuck on something long after I've 'paid my dues' (searched & tried way more than I should have to on a single issue)...

It is actually simple:

-Do what the OnMouseDown() does i the Flights Demo, but programmatically.
Private Overloads Sub OnMouseDown(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
Dim ftv = New ConnectionVisual3D(Me, ConnectionPoints(0), ConnectionPoints(1))
ftv.MyOpacity = 1.0
view1.Children.Add(ftv)

2014-07-18 EDIT:

I neglected to show how I am calling my child WPF window (the Flight Demo). This is probably important:
Private Sub mnuDisplay_DisplayEarth_click(sender As Object, e As RoutedEventArgs)
            Dim wpfEarth As New TheEarthWindow(Me)
            wpfEarth.Show()
            Dim newWindowThread As New Thread(New ThreadStart(Sub()
                                                                  Dim tempWindow As New TheEarthWindow(Me)
                                                                  AddHandler tempWindow.Closed, Sub(s2, e2) Dispatcher.CurrentDispatcher.BeginInvokeShutdown(DispatcherPriority.Background)
                                                                  tempWindow.Show()
                                                                  System.Windows.Threading.Dispatcher.Run()
                                                              End Sub))
            ' required for WPF:
            newWindowThread.SetApartmentState(ApartmentState.STA)
            ' Make the thread a background thread
            newWindowThread.IsBackground = True
            ' Start the thread
            newWindowThread.Start()
Q: I tried DOZENS of ways to open up a child WPF window, and this was the best I could do. How does spawning a child WPF Window like this impact addressing and adding children in the child window (I called the Flight Demo window "TheEarthWindow" here)?

TIA!

ORIGINAL POST FOLLOWS

I have the main thread watching a MSMQ, which feeds it 'connections'. Al lthis is fine. The problem comes when I go to add the 'connecction' to the 'earth', and I get either:
  1. The dread "The calling thread cannot access this object because a different thread owns it."
  2. Or the less frequent "This API was accessed with arguments from the wrong context."
...no matter WHAT I try... I have even gone as far as creating events & delegates, adding connections to the ObservableCollection, creating my own OCs, and every manner of delegates, invokes, and Dispatchers.

I have even tried creating my own ItemsControl in XAML, but I can't figure out how to code it for the tubes (no intellisense accepts it), or where in the 'tree' to place the following:
        <ItemsControl ItemsSource="{Binding Flights}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                        <Viewport3D /> <---???
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
Here is how I last was configured to
    Private Sub AddTheConnection(sender As Object, e As EventArgs)
        Try
            Me.childConn.MyOpacity = 1.0
            TheEarthSphere.Children.Add(childConn)
            Me.Connections.Add(childConn) ' for reference so they can be removed later...
        Catch ex As Exception
            Dim m As String = "AddTheConnection"
            log.Fatal(m & "() Exception.Message(): " & ex.Message)
            log.Fatal(m & "() Exception.ToString(): " & ex.ToString)
            log.Fatal(m & "() Exception.StackTrace(): " & ex.StackTrace)
        End Try
    End Sub
This was called any number of ways, and some attempts were without an event signature on the methods. Here is a commented summary of failures:
 ' this crashed App.run:
        'If Not Application.Current.Dispatcher.CheckAccess() Then
        '    Application.Current.Dispatcher.Invoke(New MyFunctionDelegate(AddressOf AddChildToScene))
        '    Return ' Important to leave the culprit thread
        'End If
        '=========================================================================
        ' this:
        'Me.TheEarthSphere.Children.Add(childObject)
        'TheEarthSphere.Children.Add(childObject)
        ' yields: The calling thread cannot access this object because a different thread owns it.
        '=========================================================================
        ' this:
        'Me.Dispatcher.Invoke(Sub()
        '                         TheEarthSphere.Children.Add(childObject)
        '                     End Sub)
        '' yields: This API was accessed with arguments from the wrong context.
        '=========================================================================
        ' this:
        ' MyBase.AddChild(childObject)
        ' yields: The calling thread cannot access this object because a different thread owns it.
        '=========================================================================
        ' this:
        ' Me.AddChild(childObject)
        ' yields: The calling thread cannot access this object because a different thread owns it.
        '=========================================================================
        ' this:
        'stackPanel.Dispatcher.BeginInvoke(DispatcherPriority.Normal, Sub() stackPanel.Children.Add(New TextBlock With {.Text = text})))
        'TheEarthSphere.Dispatcher.BeginInvoke(Sub()
        '                                          TheEarthSphere.Children.Add(childObject)
        '                                      End Sub)
        ' yields: Exception has been thrown by the target of an invocation.
        ' from this line in Firsty: System.Windows.Threading.Dispatcher.Run()
        '=========================================================================
        ' this:
        'Me.view1.Children.Add(childObject)
        ' yields: The calling thread cannot access this object because a different thread owns it.
        '=========================================================================
        ' this:
        'Me.view1.Dispatcher.Invoke(Sub()
        '                               view1.Children.Add(childObject)
        '                           End Sub)
        ' yields: This API was accessed with arguments from the wrong context.
        '=========================================================================
        ' this:
        ' Application.Current.Dispatcher.Invoke(New Action(Sub()
        'Me.Dispatcher.Invoke(New Action(Sub()
        '                                    TheEarthSphere.Children.Add(childObject)
        '                                End Sub))
        ' yields: The calling thread cannot access this object because a different thread owns it.
        '=========================================================================
        'Me.view1.Dispatcher.Invoke(New Action(Sub()
        '                                          'TheEarthSphere.Children.Add(childConn)
        '                                          Me.Conns.Add(childConn)
        '                                      End Sub))
        ' yields: The calling thread cannot access this object because a different thread owns it.
        '=========================================================================
        ' this:
        'Me.Dispatcher.Invoke(New Action(Sub()
        '                                    Me.Conns.Add(childConn)
        '                                End Sub))
        ' yields:
        '=========================================================================
        ' an event to allow thread communication?

        'RaiseEvent ConnectionAdded(Me, EventArgs.Empty)

        '=========================================================================
tried view1.Children.Add(childConn) and got: The calling thread cannot access this object because a different thread owns it.

Seriously, what am I going to have to do to get past this and move on?

Yours in desperation...

pat
:(