-
Jan 9th, 2017, 12:24 PM
#1
Thread Starter
New Member
Update main page when a Gelocator Position change event fires
Hallo guys,
I'm tring to write a simple mapping WPF app that use the Geolocator class to retreive the current position.
Code is simple:
Imports Windows.Devices.Geolocation 'Geolocation Namespace
Imports System.Threading 'Threading Namespace
Public NotInheritable Class MainPage
Inherits Page
Private WithEvents glGeo As New Geolocator 'Create New Geolocator Object With Its Associated Events
Private Async Sub btGetLocation_Click(sender As Object, e As RoutedEventArgs) Handles btGetLocation.Click
Try
' Find Position
Dim gpPos As Geoposition = Await glGeo.GetGeopositionAsync()
'Display Coordinates
tbLatitude.Text = gpPos.Coordinate.Point.Position.Latitude.ToString()
tbLongitude.Text = gpPos.Coordinate.Point.Position.Longitude.ToString()
Catch err As Exception
End Try
End Sub
This code show the current position when the tbGetPosition button is clicked.
But I want a continuous update so I've added the following code:
Private Sub glGeo_PositionChanged(sender As Geolocator, args As PositionChangedEventArgs) Handles glGeo.PositionChanged
Dim gpPos As Geoposition = Await glGeo.GetGeopositionAsync()
'Display Coordinates
tbLatitude.Text = gpPos.Coordinate.Point.Position.Latitude.ToString()
tbLongitude.Text = gpPos.Coordinate.Point.Position.Longitude.ToString()
End Sub
This code generate an exception in runtime because the tbLatitude and tbLongitude are not accessible form the PositionChanged thread.
Any suggestion on how to fix it ?
Thanks, Stefano
-
Jan 9th, 2017, 02:28 PM
#2
Re: Update main page when a Gelocator Position change event fires
In vb.net you would would do something along these lines...
Code:
me.invoke(Sub() tbLatitude.Text = gpPos.Coordinate.Point.Position.Latitude.ToString())
me.invoke(Sub() tbLongitude.Text = gpPos.Coordinate.Point.Position.Longitude.ToString())
or it might be more efficient to create a method that sets them both, then invoke that method...
Code:
Private Sub setLatLong
tbLatitude.Text = gpPos.Coordinate.Point.Position.Latitude.ToString()
tbLongitude.Text = gpPos.Coordinate.Point.Position.Longitude.ToString()
End sub
.
.
.
Me.Invoke(Sub() setLatLong)
(I think thatwould work. maybe not...it's by memory)
Although since this is wpf, all bets are off
Process control doesn't give you good quality, it gives you consistent quality.
Good quality comes from consistently doing the right things.
Vague general questions have vague general answers. A $100 donation is required for me to help you if you PM me asking for help. Instructions for donating to one of our local charities will be provided.
______________________________ Last edited by kebo : Now. Reason: superfluous typo's
-
Jan 9th, 2017, 05:17 PM
#3
Thread Starter
New Member
Re: Update main page when a Gelocator Position change event fires
Originally Posted by kebo
Me.Invoke(Sub() setLatLong)[/CODE](I think thatwould work. maybe not...it's by memory)
Although since this is wpf, all bets are off
Thanks Kebo.
Unfortunately invoke seem not to be a member of the main_page class in the WPF.
Any other idea ?
-
Jan 9th, 2017, 05:20 PM
#4
Re: Update main page when a Gelocator Position change event fires
You'll have to check in the WPF forum. I've asked the mods to move your thread.
Process control doesn't give you good quality, it gives you consistent quality.
Good quality comes from consistently doing the right things.
Vague general questions have vague general answers. A $100 donation is required for me to help you if you PM me asking for help. Instructions for donating to one of our local charities will be provided.
______________________________ Last edited by kebo : Now. Reason: superfluous typo's
-
Jan 9th, 2017, 05:28 PM
#5
Re: Update main page when a Gelocator Position change event fires
I don't know WPF well enough to know what a WPF-specific version of what Kebo suggested would be, but the problem is right: Only the UI thread can access UI elements.
So, the problem is that you are accessing UI elements from a background thread, but do you really need to do so? One alternative approach would be to put the information into a pair of variables and raise an event on the UI thread via the SynchronizationContext. I don't actually know whether or not that's a WPF thing, either, but I would expect that it would be. You'd store the current context when you are in the UI thread (store it one time, it's just a context), then from a background thread, you can use that stored context to .Post a call, which will be run on the thread for the context, which would be the UI thread, in this case.
That may be overly complicated for this, but you ARE talking about geolocation data. If the ONLY thing you are doing with that data is showing it in the labels, then messing around with the SynchronizationContext, simple though it is, may be more work than it is worth. However, if you want to do anything else with that data, you'd want to keep it as numbers rather than keeping it as strings in labels, in which case this approach would be worth it.
My usual boring signature: Nothing
-
Jan 10th, 2017, 02:12 PM
#6
Thread Starter
New Member
Re: Update main page when a Gelocator Position change event fires
Thanks Shaggy Hiker. The SynchronizationContext is the solution
No need to use variable to store data. The real point is to fire the sub when new data are available (PositionChanged event).
here is the working code. Very simple and cleaver:
Public NotInheritable Class MainPage
Inherits Page
Private context As SynchronizationContext = SynchronizationContext.Current
Private WithEvents glGeo As New Geolocator 'Create New Geolocator Object With Its Associated Events
Private ctsCancel As CancellationTokenSource 'Cancel The Spawned Thread
Private Sub glGeo_PositionChanged(sender As Geolocator, args As PositionChangedEventArgs) Handles glGeo.PositionChanged
Me.context.Post(AddressOf update_data, Nothing)
End Sub
Private Async Sub update_data()
Try
ctsCancel = New CancellationTokenSource()
Dim canToken As CancellationToken = ctsCancel.Token
' Find Position
Dim gpPos As Geoposition = Await glGeo.GetGeopositionAsync().AsTask(canToken)
'Display Coordinates
tbLatitude.Text = gpPos.Coordinate.Point.Position.Latitude.ToString()
tbLongitude.Text = gpPos.Coordinate.Point.Position.Longitude.ToString()
Catch err As Exception
End Try
End Sub
End class
Thanks, Stefano
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|