You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过API更新Xamarin iOS谷歌地图自定义PIN上的信息

Xamarin iOS 谷歌地图自定义Pin更新问题解决

问题根因

  1. 空引用异常:你在Task.Run开启的后台线程中直接操作customMap.Pins等UI控件,Xamarin要求所有UI相关操作必须在主线程执行,后台线程操作UI会导致控件状态异常,触发空引用错误。
  2. InfoBox不更新:CustomPin类未实现INotifyPropertyChanged接口,属性值修改后无法通知UI自动刷新,所以即使字段值修改成功,界面展示的信息也不会同步更新。

修复步骤

方案1(推荐:无需清空重加Pin)

让CustomPin实现属性变更通知接口,修改属性后自动触发UI刷新:

using System.ComponentModel;
using System.Runtime.CompilerServices;
using Xamarin.Forms.Maps;

public class CustomPin : Pin, INotifyPropertyChanged
{
    private int _alertLevel;
    private int _codeNum;
    private int _mapCode;

    public int AlertLevel
    {
        get => _alertLevel;
        set
        {
            _alertLevel = value;
            OnPropertyChanged();
            // 如果InfoBox展示内容依赖AlertLevel/CodeNum/MapCode拼接,同步触发关联属性的变更通知
            OnPropertyChanged(nameof(Label));
            OnPropertyChanged(nameof(Address));
        }
    }

    public int CodeNum
    {
        get => _codeNum;
        set
        {
            _codeNum = value;
            OnPropertyChanged();
            OnPropertyChanged(nameof(Label));
        }
    }

    public int MapCode
    {
        get => _mapCode;
        set
        {
            _mapCode = value;
            OnPropertyChanged();
            OnPropertyChanged(nameof(Address));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

修改APIConnection方法,增加非空判断和属性更新逻辑:

public async Task APIConnection(List<CustomPin> pins)
{
    WaterBindingData waterData = await _restServiceData.GetWaterDataForecast(
        GenerateRequestUri(Constants.EndPoint), 
        GenerateRequestUriStations(Constants.EndPoint));
    
    // 增加非空判断避免空引用
    if(waterData?.WaterStation?.Stations == null) return;
            
    foreach (var water in waterData.WaterStation.Stations)
    {
        int codeNum = water.CodeNum;
        int level = water.AlertLevelStation;
        int mapcode = water.MapCode;

        foreach (var item in pins)
        {
            if (item.CodeNum == water.CodeNum)
            {
                // 直接更新属性,自动触发UI刷新
                item.AlertLevel = level;
                item.CodeNum = codeNum;
                item.MapCode = mapcode;
                // 如果Label/Address是固定文本,直接在这里修改值即可
                // item.Label = $"站点{codeNum} 预警等级{level}";
                // item.Address = $"地图编码{mapcode}";
            }
        }
    }
}

修改API调用代码,去掉不必要的Task.Run:

// 原代码:Task.Run(async () => await APIConnection(customMap.CustomPins));
// 替换为,避免额外线程开销
_ = APIConnection(customMap.CustomPins);
// 如果当前上下文是异步方法,直接await调用即可
// await APIConnection(customMap.CustomPins);

方案2(坚持清空重加Pin)

如果需要强制刷新所有Pin,把UI操作调度到主线程执行:

public async Task APIConnection(List<CustomPin> pins)
{
    WaterBindingData waterData = await _restServiceData.GetWaterDataForecast(
        GenerateRequestUri(Constants.EndPoint), 
        GenerateRequestUriStations(Constants.EndPoint));
    
    if(waterData?.WaterStation?.Stations == null) return;
            
    foreach (var water in waterData.WaterStation.Stations)
    {
        int codeNum = water.CodeNum;
        int level = water.AlertLevelStation;
        int mapcode = water.MapCode;

        foreach (var item in pins)
        {
            if (item.CodeNum == water.CodeNum)
            {
                item.AlertLevel = level;
                item.CodeNum = codeNum;
                item.MapCode = mapcode;
                item.Label = $"更新后的Label内容";
                item.Address = $"更新后的Address内容";
            }
        }
    }

    // UI操作必须放到主线程执行
    Device.BeginInvokeOnMainThread(() =>
    {
        customMap.Pins.Clear();
        foreach(var item in pins)
        {
            customMap.Pins.Add(item);
        }
        // 同步更新CustomPins集合,避免自定义渲染器逻辑异常
        customMap.CustomPins = new List<CustomPin>(pins);
    });
}

内容的提问来源于stack exchange,提问作者Blagovest Pizhev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 17:09:03