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

Xamarin.Forms中DevExpress DataGridView Tap触发对象引用未设置错误

Xamarin.Forms 真机APK空引用错误排查(模拟器调试正常)

问题背景

开发Xamarin.Forms查询页面,通过动态对象自动生成DevExpress DataGridView实现查询参数复用与切换。模拟器调试时功能正常,但将Visual Studio生成的APK安装到真机后,触发「未将对象引用设置到对象实例」错误,无法定位具体问题点。相关点击事件代码如下:

private async void dataTable_Tap(object sender, DevExpress.XamarinForms.DataGrid.DataGridGestureEventArgs e)
{
    try
    {
        var menuItem = (DevExpress.XamarinForms.DataGrid.DataGridView)sender;
        if (menuItem != null)
        {
            if (e != null)
            {
                dynamic dItem = e.Item;
                if (dItem != null)
                {
                    string queryParameter = Preferences.Get("queryParameters", "");
                    queryParameter += dItem[vNumber] + pid + ";;";
                    Preferences.Set("queryParameters", queryParameter);
                    Console.WriteLine(queryParameter);
                    await PopupNavigation.Instance.PopAsync();
                    DependencyService.Get<IMessage>().UzunMesaj($"{dItem[vNumber]}");
                }
            }
        }
    }
    catch (Exception ex)
    {
        await DisplayAlert("", $"Can not select : \n{ex.Message}", "Tmm");
        throw;
    }
}

可能的错误原因及解决方案

1. 动态对象dItem的运行时绑定问题

Release模式下(APK默认是Release编译),编译器优化可能导致动态对象的成员访问失效,而Debug模式的模拟器会保留更多运行时绑定信息。

  • 替代方案:将动态对象转为IDictionary<string, object>(如果e.Item是匿名类型或字典),通过键值对安全访问成员:
    if (e.Item is IDictionary<string, object> itemDict)
    {
        if (itemDict.TryGetValue(vNumber, out var vNumberValue) && vNumberValue != null)
        {
            // 后续逻辑使用vNumberValue
        }
    }
    

2. PopupNavigation.Instance未初始化

真机环境中,PopupNavigation的实例可能未被正确初始化,导致调用PopAsync()时空引用。

  • 解决方案:调用前先判空:
    if (PopupNavigation.Instance != null)
    {
        await PopupNavigation.Instance.PopAsync();
    }
    

3. DependencyService.Get<IMessage>()返回null

Release模式下链接器可能移除了IMessage的实现类,或者未正确注册依赖服务。

  • 解决方案:
    • 在平台项目的实现类上添加[assembly: Dependency(typeof(MessageImplementation))]特性;
    • 在Release链接器设置中排除相关程序集,或给实现类添加[Preserve]特性避免被优化移除。

4. pid变量未初始化

代码中直接使用pid变量,但未展示其赋值逻辑,若pid为null,字符串拼接时会引发空引用。

  • 解决方案:使用前确保pid有值,或默认空字符串:
    string pidValue = pid ?? string.Empty;
    queryParameter += $"{vNumberValue}{pidValue};;";
    

5. 真机调试定位具体错误

最直接的方式是开启真机调试:

  • 在Visual Studio中选择真机作为调试目标,部署APK并启动调试;
  • 触发错误时,查看调用栈定位具体空引用的代码行;
  • 关键步骤添加日志输出(如Console.WriteLine),通过Android Logcat或iOS Console查看真机日志。

修改后的示例代码

private async void dataTable_Tap(object sender, DevExpress.XamarinForms.DataGrid.DataGridGestureEventArgs e)
{
    try
    {
        if (sender is not DevExpress.XamarinForms.DataGrid.DataGridView)
            return;
        if (e?.Item == null)
            return;

        if (e.Item is IDictionary<string, object> itemDict)
        {
            if (!itemDict.TryGetValue(vNumber, out var vNumberValue) || vNumberValue == null)
            {
                await DisplayAlert("", "无法获取指定参数", "确定");
                return;
            }

            string pidValue = pid ?? string.Empty;
            string queryParameter = Preferences.Get("queryParameters", "");
            queryParameter += $"{vNumberValue}{pidValue};;";
            Preferences.Set("queryParameters", queryParameter);
            Console.WriteLine(queryParameter);

            if (PopupNavigation.Instance != null)
            {
                await PopupNavigation.Instance.PopAsync();
            }

            var messageService = DependencyService.Get<IMessage>();
            messageService?.UzunMesaj($"{vNumberValue}");
        }
        else
        {
            await DisplayAlert("", "数据格式不支持", "确定");
        }
    }
    catch (Exception ex)
    {
        await DisplayAlert("", $"选择失败:\n{ex.Message}", "确定");
    }
}

内容的提问来源于stack exchange,提问作者Mert Altiparmak

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 14:53:12