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

