Skip to content

Commit 4ab1b51

Browse files
Implement MapClicked (#1269)
* Implement MapClicked * Update MapHandler.Windows.cs * Update src/CommunityToolkit.Maui.Maps/Handler/Map/MapHandler.Windows.cs Co-authored-by: Vladislav Antonyuk <33021114+VladislavAntonyuk@users.noreply.github.com> * Gracefully handle empty strings & Move Types --------- Co-authored-by: Vladislav Antonyuk <33021114+VladislavAntonyuk@users.noreply.github.com>
1 parent 8d71db2 commit 4ab1b51

File tree

8 files changed

+125
-44
lines changed

8 files changed

+125
-44
lines changed

samples/CommunityToolkit.Maui.Sample/Pages/Views/Maps/MapsPinsPage.xaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@
1414
<Button Text="Remove Pin" Clicked="RemovePin_Clicked" />
1515
<Button Text="Add 10 Pins" Clicked="Add10Pins_Clicked" />
1616
</HorizontalStackLayout>
17-
<Map x:Name="PinsMap" Grid.Row="1" />
17+
<Map x:Name="PinsMap" Grid.Row="1" MapClicked="PinsMap_MapClicked" />
1818
</Grid>
1919
</pages:BasePage>

samples/CommunityToolkit.Maui.Sample/Pages/Views/Maps/MapsPinsPage.xaml.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,9 @@ void InitRegion_OnClicked(object? sender, EventArgs e)
114114

115115
PinsMap.Pins.Add(microsoftPin);
116116
}
117+
118+
void PinsMap_MapClicked(object sender, MapClickedEventArgs e)
119+
{
120+
DisplayAlert("Map Clicked", $"Location {e.Location.Latitude}, {e.Location.Longitude}", "OK");
121+
}
117122
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace CommunityToolkit.Maui.Maps.Handlers;
2+
3+
class Bounds
4+
{
5+
public Center? Center { get; set; }
6+
public double Width { get; set; }
7+
public double Height { get; set; }
8+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace CommunityToolkit.Maui.Maps.Handlers;
2+
3+
class Center
4+
{
5+
public double Latitude { get; set; }
6+
public double Longitude { get; set; }
7+
public int Altitude { get; set; }
8+
public int AltitudeReference { get; set; }
9+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace CommunityToolkit.Maui.Maps.Handlers;
2+
3+
enum EventIdentifier
4+
{
5+
Unknown,
6+
InfoWindowClicked,
7+
BoundsChanged,
8+
MapClicked,
9+
PinClicked,
10+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace CommunityToolkit.Maui.Maps.Handlers;
2+
3+
class EventMessage
4+
{
5+
public string Id { get; set; } = string.Empty;
6+
7+
public object? Payload { get; set; }
8+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace CommunityToolkit.Maui.Maps.Handlers;
2+
3+
class InfoWindow
4+
{
5+
public string InfoWindowMarkerId { get; set; } = string.Empty;
6+
}

src/CommunityToolkit.Maui.Maps/Handler/Map/MapHandler.Windows.cs

Lines changed: 78 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public partial class MapHandlerWindows : MapHandler
1818
internal static string? MapsKey;
1919
MapSpan? regionToGo;
2020

21-
JsonSerializerOptions jsonSerializerOptions = new()
21+
readonly JsonSerializerOptions jsonSerializerOptions = new()
2222
{
2323
PropertyNameCaseInsensitive = true
2424
};
@@ -191,7 +191,20 @@ function loadMap() {
191191
showTrafficButton: false
192192
});
193193
loadTrafficModule();
194-
Microsoft.Maps.Events.addHandler(map, 'viewrendered', function () { var bounds = map.getBounds(); invokeHandlerAction(bounds); });
194+
Microsoft.Maps.Events.addHandler(map, 'viewrendered', function () { var bounds = map.getBounds(); invokeHandlerAction('BoundsChanged', bounds); });
195+
196+
Microsoft.Maps.Events.addHandler(map, 'click', function (e) {
197+
if (!e.isPrimary) {
198+
return;
199+
}
200+
201+
var clickedLocation = {
202+
latitude: e.location.latitude,
203+
longitude: e.location.longitude
204+
};
205+
206+
invokeHandlerAction('MapClicked', clickedLocation);
207+
});
195208
196209
infobox = new Microsoft.Maps.Infobox(map.getCenter(), {
197210
visible: false
@@ -206,7 +219,7 @@ function loadMap() {
206219
infoWindowMarkerId: infobox.infoWindowMarkerId
207220
};
208221
209-
invokeHandlerAction(infoWindow);
222+
invokeHandlerAction('InfoWindowClicked', infoWindow);
210223
});
211224
}
212225
@@ -323,13 +336,18 @@ function addPin(latitude, longitude, label, address, id)
323336
location: e.target.getLocation(),
324337
markerId: e.target.markerId
325338
};
326-
invokeHandlerAction(clickedPin);
339+
invokeHandlerAction('PinClicked', clickedPin);
327340
});
328341
}
329342
330-
function invokeHandlerAction(data)
343+
function invokeHandlerAction(id, data)
331344
{
332-
window.chrome.webview.postMessage(data);
345+
var eventMessage = {
346+
id: id,
347+
payload: data
348+
};
349+
350+
window.chrome.webview.postMessage(eventMessage);
333351
}
334352
</script>
335353
<style>
@@ -366,54 +384,71 @@ void WebViewNavigationCompleted(WebView2 sender, CoreWebView2NavigationCompleted
366384

367385
void WebViewWebMessageReceived(WebView2 sender, CoreWebView2WebMessageReceivedEventArgs args)
368386
{
369-
// TODO make this better, separate events?
370-
var clickedPinWebView = JsonSerializer.Deserialize<Pin>(args.WebMessageAsJson, jsonSerializerOptions);
371-
var clickedPinWebViewId = clickedPinWebView?.MarkerId?.ToString();
372-
373-
if (!string.IsNullOrEmpty(clickedPinWebViewId))
387+
// For some reason the web message is empty
388+
if (string.IsNullOrEmpty(args.WebMessageAsJson))
374389
{
375-
var clickedPin = VirtualView.Pins.SingleOrDefault(p => (p as Pin)?.Id.ToString().Equals(clickedPinWebViewId) ?? false);
376-
377-
clickedPin?.SendMarkerClick();
378390
return;
379391
}
380392

381-
var clickedInfoWindowWebView = JsonSerializer.Deserialize<InfoWindow>(args.WebMessageAsJson, jsonSerializerOptions);
382-
var clickedInfoWindowWebViewId = clickedInfoWindowWebView?.InfoWindowMarkerId;
393+
var eventMessage = JsonSerializer.Deserialize<EventMessage>(args.WebMessageAsJson, jsonSerializerOptions);
383394

384-
if (!string.IsNullOrEmpty(clickedInfoWindowWebViewId))
395+
// The web message (or it's ID) could not be deserialized to something we recognize
396+
if (eventMessage is null || !Enum.TryParse<EventIdentifier>(eventMessage.Id, true, out var eventId))
385397
{
386-
var clickedPin = VirtualView.Pins.SingleOrDefault(p => (p as Pin)?.Id.ToString().Equals(clickedInfoWindowWebViewId) ?? false);
387-
388-
clickedPin?.SendInfoWindowClick();
389398
return;
390399
}
391400

392-
var mapRect = JsonSerializer.Deserialize<Bounds>(args.WebMessageAsJson, jsonSerializerOptions);
393-
if (mapRect?.Center is not null)
401+
var payloadAsString = eventMessage.Payload?.ToString();
402+
403+
// The web message does not have a payload
404+
if (string.IsNullOrWhiteSpace(payloadAsString))
394405
{
395-
VirtualView.VisibleRegion = new MapSpan(new Location(mapRect.Center.Latitude, mapRect.Center.Longitude),
396-
mapRect.Height, mapRect.Width);
406+
return;
397407
}
398-
}
399-
400-
class InfoWindow
401-
{
402-
public string InfoWindowMarkerId { get; set; } = string.Empty;
403-
}
404408

405-
class Center
406-
{
407-
public double Latitude { get; set; }
408-
public double Longitude { get; set; }
409-
public int Altitude { get; set; }
410-
public int AltitudeReference { get; set; }
411-
}
412-
413-
class Bounds
414-
{
415-
public Center? Center { get; set; }
416-
public double Width { get; set; }
417-
public double Height { get; set; }
409+
switch (eventId)
410+
{
411+
case EventIdentifier.BoundsChanged:
412+
var mapRect = JsonSerializer.Deserialize<Bounds>(payloadAsString, jsonSerializerOptions);
413+
if (mapRect?.Center is not null)
414+
{
415+
VirtualView.VisibleRegion = new MapSpan(new Location(mapRect.Center.Latitude, mapRect.Center.Longitude),
416+
mapRect.Height, mapRect.Width);
417+
}
418+
break;
419+
case EventIdentifier.MapClicked:
420+
var clickedLocation = JsonSerializer.Deserialize<Location>(payloadAsString,
421+
jsonSerializerOptions);
422+
if (clickedLocation is not null)
423+
{
424+
VirtualView.Clicked(clickedLocation);
425+
}
426+
break;
427+
428+
case EventIdentifier.InfoWindowClicked:
429+
var clickedInfoWindowWebView = JsonSerializer.Deserialize<InfoWindow>(payloadAsString,
430+
jsonSerializerOptions);
431+
var clickedInfoWindowWebViewId = clickedInfoWindowWebView?.InfoWindowMarkerId;
432+
433+
if (!string.IsNullOrEmpty(clickedInfoWindowWebViewId))
434+
{
435+
var clickedPin = VirtualView.Pins.SingleOrDefault(p => (p as Pin)?.Id.ToString().Equals(clickedInfoWindowWebViewId) ?? false);
436+
437+
clickedPin?.SendInfoWindowClick();
438+
}
439+
break;
440+
441+
case EventIdentifier.PinClicked:
442+
var clickedPinWebView = JsonSerializer.Deserialize<Pin>(payloadAsString, jsonSerializerOptions);
443+
var clickedPinWebViewId = clickedPinWebView?.MarkerId?.ToString();
444+
445+
if (!string.IsNullOrEmpty(clickedPinWebViewId))
446+
{
447+
var clickedPin = VirtualView.Pins.SingleOrDefault(p => (p as Pin)?.Id.ToString().Equals(clickedPinWebViewId) ?? false);
448+
449+
clickedPin?.SendMarkerClick();
450+
}
451+
break;
452+
}
418453
}
419454
}

0 commit comments

Comments
 (0)