【问题标题】:Xamarin Forms Geocoder: no compilation or runtime errors, and no resultsXamarin Forms Geocoder:没有编译或运行时错误,也没有结果
【发布时间】:2017-01-13 21:50:43
【问题描述】:

我一直在使用 this 指南构建一个启用映射的基于 Xamarin Forms 的应用程序。地图工作没有任何问题;但是,地理编码功能正在静默失败。

我的视图包含一个SearchBox,它连接到一个命令,该命令使用 Xamarin Forms Geocoder 实例来查找用户定义的地址。在SearchBox 中输入地址时,该命令正确触发:

但是,当我在调试时,Geocoder 会立即返回,返回时根本没有任何结果。该操作发生在下面的geocodeAddress 函数中:

type DashboardViewModel(?host: IScreen, ?platform: IPlatform) as this =
    inherit ReactiveViewModel()
    let host, platform = LocateIfNone host, LocateIfNone platform
    let searchResults = new ObservableCollection<GeodesicLocation>()
    let geocodeAddress(vm: DashboardViewModel) =
        let vm = match box vm with | null -> this | _ -> vm
        searchResults.Clear()
        async {
            let! results = platform.Geocoder.GetPositionsForAddressAsync(vm.SearchAddress) |> Async.AwaitTask
            results |> Seq.map (fun r -> new GeodesicLocation(r.Latitude * 1.0<deg>, r.Longitude * 1.0<deg>)) |> Seq.iter searchResults.Add
        } |> Async.StartAsTask
    let searchForAddress = ReactiveCommand.CreateFromTask geocodeAddress
    let mutable location = new GeodesicLocation()
    let mutable searchAddress = String.Empty
    member __.Title with get() = LocalisedStrings.AppTitle
    member __.SearchForAddress with get() = searchForAddress
    member this.SearchAddress with get() = searchAddress and set(value) = this.RaiseAndSetIfChanged(&searchAddress, value, "SearchAddress") |> ignore
    member this.LatitudeDegrees 
        with get() = location.Latitude / 1.0<deg> 
        and set(value) = location <- new GeodesicLocation(value * 1.0<deg>, location.Longitude); this.RaisePropertyChanged("LatitudeDegrees")
    member this.LongitudeDegrees 
        with get() = location.Longitude / 1.0<deg> 
        and set(value) = location <- new GeodesicLocation(location.Latitude, value * 1.0<deg>); this.RaisePropertyChanged("LongitudeDegrees")
    interface IRoutableViewModel with
        member __.HostScreen = host
        member __.UrlPathSegment = "Dashboard"

根据 Xamarin docsGeocoder 类应该开箱即用。我是否缺少某种设置?

UPDATE:视图的代码如下。这不是使用 XAML 构建的,但它是基于 F# 的结构,与 XAML 相当相似。

type DashboardView(theme: Theme) as this = 
    inherit ContentPage<DashboardViewModel, DashboardView>(theme)
    new() = new DashboardView(Themes.AstridTheme)
    override __.CreateContent() =
        theme.GenerateGrid([|"Auto"; "*"|], [|"*"|]) |> withColumn(
            [|
                theme.VerticalLayout() |> withBlocks(
                    [|
                        theme.GenerateLabel(fun l -> this.Title <- l) 
                            |> withAlignment LayoutOptions.Center LayoutOptions.Center
                            |> withOneWayBinding(this.ViewModel, this, <@ fun (vm: DashboardViewModel) -> vm.Title @>, <@ fun (v: DashboardView) -> (v.Title: Label).Text @>)
                        theme.GenerateSearchBar(fun sb -> this.AddressSearchBar <- sb)
                            |> withSearchBarPlaceholder LocalisedStrings.SearchForAPlaceOfInterest
                            |> withTwoWayBinding(this.ViewModel, this, <@ fun (vm: DashboardViewModel) -> vm.SearchAddress @>, <@ fun (v: DashboardView) -> (v.AddressSearchBar: SearchBar).Text @>)
                            |> withSearchCommand this.ViewModel.SearchForAddress
                    |])
                theme.GenerateMap(new GeodesicLocation(51.4<deg>, 0.0<deg>), 4.0<km>, fun m -> this.Map <- m)
                    |> withTwoWayBinding(this.ViewModel, this, <@ fun (vm: DashboardViewModel) -> vm.LatitudeDegrees @>, <@ fun (v:DashboardView) -> (v.Map: Map).VisibleRegion.LatitudeDegrees @>)
                    |> withTwoWayBinding(this.ViewModel, this, <@ fun (vm: DashboardViewModel) -> vm.LongitudeDegrees @>, <@ fun (v:DashboardView) -> (v.Map: Map).VisibleRegion.LongitudeDegrees @>)
            |]) |> createFromColumns :> View
    member val AddressSearchBar = Unchecked.defaultof<SearchBar> with get, set
    member val Title = Unchecked.defaultof<Label> with get, set
    member val Map = Unchecked.defaultof<Map> with get, set

【问题讨论】:

  • 你能显示 xaml 吗?
  • 我将编辑问题以向您展示视图(不是使用 XAML 构建的)。

标签: google-maps f# xamarin.forms geocoding


【解决方案1】:

看起来这是 Visual Studio 模拟器的问题。当我通过 USB 在我的设备上运行调试器时,找到正确的结果没有问题。

【讨论】:

    【解决方案2】:

    通过查看您的代码,我怀疑问题是您需要为searchResults 创建一个公共属性,并从地图中绑定它:

    member this.SearchResults with get() = searchResults
    

    这将允许您绑定搜索结果。

    在异步工作流中添加到searchResults 之前,您可能还需要切换到 UI 线程上下文。在后台线程中添加 ObservableCollection&lt;'T&gt; 通常不会导致任何内容被渲染或崩溃。

    【讨论】:

    • 恐怕还没到这个程度。 results 集合始终为空。我正在使用 ReactiveUI,所以我可能应该做一些复杂的事情,比如使用 ReactiveCollection 并在 UI 线程上观察它。麻烦的是,如果我没有找到任何结果,那么 UI 线程将无事可做。
    猜你喜欢
    • 2018-10-23
    • 1970-01-01
    • 2021-05-27
    • 1970-01-01
    • 2013-12-26
    • 2014-06-19
    • 2016-12-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多