C# 尝试Geolocator.GetPositionAsync()时,Geolocator.PositionChanged事件会引发

C# 尝试Geolocator.GetPositionAsync()时,Geolocator.PositionChanged事件会引发,c#,xaml,geolocation,bing-maps,C#,Xaml,Geolocation,Bing Maps,因此,在我的应用程序中使用GetPositionAsync方法获取当前位置时,我遇到了一些奇怪的行为。当我查询位置时,它似乎正在触发PositionChanged事件。我不确定到底发生了什么,而且很难调试,因为调用是异步的。下面是一些说明问题的示例代码(您需要一个Bing Maps密钥来测试它): MainPage.xaml.cs using System; using Bing.Maps; using Windows.UI.Xaml.Input; using Windows.Devices.G

因此,在我的应用程序中使用GetPositionAsync方法获取当前位置时,我遇到了一些奇怪的行为。当我查询位置时,它似乎正在触发PositionChanged事件。我不确定到底发生了什么,而且很难调试,因为调用是异步的。下面是一些说明问题的示例代码(您需要一个Bing Maps密钥来测试它):

MainPage.xaml.cs

using System;
using Bing.Maps;
using Windows.UI.Xaml.Input;
using Windows.Devices.Geolocation;
using Windows.UI.Core;
using GeoPositionExercise.Model;

namespace GeoPositionExercise
{
    public sealed partial class MainPage
    {
        private Geolocator _geolocator;
        private LocationIcon _locationIcon = new LocationIcon();

        public MainPage()
        {
            InitializeComponent();

            MyMap.Children.Add(_locationIcon);
            _geolocator = new Geolocator();

            //LoadPoly(PolyLayer, DefaultStyle, GetLocation);
            _geolocator.PositionChanged += this._geolocator_PositionChanged;

        }

        private void _geolocator_PositionChanged(Geolocator sender, PositionChangedEventArgs args)
        {
            this.Dispatcher.RunAsync(CoreDispatcherPriority.Low, new DispatchedHandler(
                () =>
                {
                    displayPosition(this, args.Position.Coordinate);
                }));
        }

        private void displayPosition(object sender, Geocoordinate coordinate)
        {
            Location location = new Location(coordinate.Latitude, coordinate.Longitude);

            MapLayer.SetPosition(_locationIcon, location);
            MyMap.SetView(location, 15.0f);
        } 

        private async void GetLocation(object sender, TappedRoutedEventArgs e)
        {
            // This raises a PositionChanged event for some reason
            var position = await _geolocator.GetGeopositionAsync();
        }
    }
}
MainPage.xaml

<common:PageBase xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                 xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
                 xmlns:common="using:GeoPositionExercise.Common"
                 xmlns:local="using:GeoPositionExercise"
                 xmlns:ignore="http://www.ignore.com"
                 x:Name="PageRoot"
                 x:Class="GeoPositionExercise.MainPage"
                 xmlns:m="using:Bing.Maps"
                 mc:Ignorable="d ignore"
                 DataContext="{Binding Main, Source={StaticResource Locator}}">

    <Page.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Skins/MainSkin.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Page.Resources>

    <Page.BottomAppBar>
        <AppBar>
            <AppBarButton Label="Get Location" Tapped="GetLocation">
                <AppBarButton.Icon>
                    <FontIcon Glyph="&#xE118;" />
                </AppBarButton.Icon>
            </AppBarButton>
        </AppBar>
    </Page.BottomAppBar>

    <Grid x:Name="MainGrid" Background="{StaticResource ApplicationPageBackgroundThemeBrush}" Margin="0,0,0,53">
        <m:Map x:Name="MyMap" Credentials="YOUR BING MAP KEY HERE" >
            <m:MapLayer x:Name="PinLayer"/>
            <m:MapLayer x:Name="InfoboxLayer" Visibility="Collapsed">
                <Grid x:Name="Infobox" Width="350">
                    <Border Background="Black" Opacity="0.8" BorderBrush="White" BorderThickness="2" CornerRadius="5"/>
                    <Grid Margin="5">
                        <StackPanel HorizontalAlignment="Left" Margin="10">
                            <TextBlock x:Name="InfoboxTitle" FontSize="18" Width="290" HorizontalAlignment="Left" TextWrapping="Wrap" />
                            <WebView x:Name="InfoboxDescription" Width="330" Height="100" Margin="0,10,0,0"/>
                        </StackPanel>
                    </Grid>
                </Grid>
            </m:MapLayer>
        </m:Map>
    </Grid>
</common:PageBase>

最后是一个用户控件位置图标:

<UserControl
    x:Class="GeoPositionExercise.Model.LocationIcon"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:GeoPositionExercise.Model"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300"
    d:DesignWidth="400">
    <Canvas>
        <Ellipse Height="25" Width="25" Fill="#FFF0F0F0" Margin="-12.5,-12.5,0,0"></Ellipse>
        <Ellipse Height="20" Width="20" Fill="Black" Margin="-10,-10,0,0"></Ellipse>
        <Ellipse Height="10" Width="10" Fill="White" Margin="-5,-5,0,0"></Ellipse>
    </Canvas>
</UserControl>


在编译之前,请确保具有正确的引用并以X64或x82平台为目标。您可以通过单击“获取位置”应用程序栏按钮进行测试,它将始终将地图居中于当前位置。我不太清楚为什么会发生这种情况,因为我唯一调用displayPosition的地方是在_Geologicator_PostionChanged方法中。

一个解决办法是在使用SetPosition更新同一位置之前检查MapLayer的当前位置。此外,您可能希望签出相同的StatusChanged事件。它不会“出于某种原因”引发事件。对该方法的调用应该引发PositionChanged事件,因为会计算新的位置。在什么情况下,这会给您带来问题?您的
\u geological\u PositionChanged
方法会被(重复)调用,因为您已将其添加到
PositionChanged
事件中。这就是地理定位器的工作原理。添加处理程序将启动位置更新。您不需要任何额外的
GetGeopositionAsync
。只需使用
PositionChanged
提供的最后一个位置。有关工作示例,请参阅中的
PhoneApplication
示例应用程序。我没有意识到GetGeopositionAsync应该调用PositionChanged事件,并且没有看到任何文档。但是,我的想法是错误的。我可以在调用PositionChanged时保存当前位置,并在整个应用程序中使用它,而不是在需要时查询它。谢谢