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

Xamarin.Forms中Picker值存入SQLite遇TargetInvocationException问题求助

排查Xamarin.Forms Picker值存入SQLite时的TargetInvocationException异常

这个TargetInvocationException通常是一个包装异常,真正的错误原因藏在它的InnerException属性里。不过从你提供的代码来看,我能定位几个明显的问题,一步步来修复:

1. 模型类AdLogEntry的致命问题

SQLite在序列化/反序列化对象时,对属性有严格要求:

  • LoadedDate没有setter:SQLite需要属性有公共的set方法才能写入数据,你的这个属性只有get,会导致反射赋值失败。
    修复:改成自动属性,如果需要默认值可以在构造函数里初始化:
    public DateTime LoadedDate { get; set; } = DateTime.Now; // 示例默认值,可根据需求调整
    
  • GetDatePicker是UI控件类型:SQLite无法序列化DatePicker这种UI控件对象,这个属性完全不应该出现在数据库模型里。如果是要存储选中的日期,应该用DateTime类型的属性,而不是控件本身。
    修复:直接移除这个属性:
    // 删掉这一行:public DatePicker GetDatePicker { get; }
    

2. Picker SelectedItem的类型转换错误

看你的XAML代码,SectionPicker的ItemsSource绑定的是Sections集合,并且用ItemDisplayBinding="{Binding SectionName}",说明Sections里的元素是自定义对象(比如一个Section类,包含SectionName属性),而不是字符串。但你在代码里直接把SelectedItem强制转成string:

Section = (string)SectionPicker.SelectedItem,

这会抛出InvalidCastException,被包装成TargetInvocationException。

修复方法:先把SelectedItem转成对应的对象类型,再取对应的属性值。假设你的Sections集合是List<Section>,其中Section类有SectionName属性;AnimalCategories是List<AnimalCategory>,包含AnimalKind属性:

// 处理SectionPicker
var selectedSection = SectionPicker.SelectedItem as Section;
// 处理CategoryPicker
var selectedCategory = CategoryPicker.SelectedItem as AnimalCategory;

AdLogEntry adLogEntry = new AdLogEntry {
    Location = LocationEntry.Text,
    Price = PriceEntry.Text,
    Name = NameEntry.Text,
    Section = selectedSection?.SectionName, // 取对象的SectionName属性
    AnimalCategory = selectedCategory?.AnimalKind, // 同理取AnimalKind属性
};

注意加上?空值判断,避免Picker未选择时出现空引用异常。

3. 保存逻辑的条件判断错误

你现在的判断用的是||(或),这意味着只要任意一个必填字段不为空就会执行保存,这显然不符合“必填字段都要填写”的预期:

if (!string.IsNullOrWhiteSpace(NameEntry.Text) || (!string.IsNullOrWhiteSpace(PriceEntry.Text) || (!string.IsNullOrWhiteSpace(LocationEntry.Text) )))

修复:改成&&(与),确保所有必填字段都不为空:

if (!string.IsNullOrWhiteSpace(NameEntry.Text) 
    && !string.IsNullOrWhiteSpace(PriceEntry.Text) 
    && !string.IsNullOrWhiteSpace(LocationEntry.Text))

4. 捕获真实异常的调试技巧

为了以后快速定位问题,建议在保存方法里加上try-catch,直接获取InnerException的信息:

private async Task SaveAdLog()
{
    try
    {
        // 原有的判断和保存逻辑
        if (!string.IsNullOrWhiteSpace(NameEntry.Text) 
            && !string.IsNullOrWhiteSpace(PriceEntry.Text) 
            && !string.IsNullOrWhiteSpace(LocationEntry.Text))
        {
            var selectedSection = SectionPicker.SelectedItem as Section;
            var selectedCategory = CategoryPicker.SelectedItem as AnimalCategory;

            AdLogEntry adLogEntry = new AdLogEntry {
                Location = LocationEntry.Text,
                Price = PriceEntry.Text,
                Name = NameEntry.Text,
                Section = selectedSection?.SectionName,
                AnimalCategory = selectedCategory?.AnimalKind,
            };
            _adService.CreateAddLogEntry(adLogEntry);
            await DisplayAlert(LabelCZ.AlertThankYou, LabelCZ.AlertSpace, LabelCZ.AlertOk);
        }
        else
        {
            await DisplayAlert(LabelCZ.AlertRequired, LabelCZ.AlertRequiredPlease, LabelCZ.AlertOk);
        }
    }
    catch (Exception ex)
    {
        var realError = ex.InnerException ?? ex;
        await DisplayAlert("保存失败", $"错误原因:{realError.Message}", "确定");
        System.Diagnostics.Debug.WriteLine($"保存错误详情:{realError}");
    }
}

按照上面的步骤修复后,你的异常应该就能解决了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 21:17:48