【发布时间】:2023-02-22 17:01:41
【问题描述】:
我正在使用 Xamarin 为学校开展一个项目。我对 Xamarin 不是很熟悉,所以我会尽力解释我的问题。我的应用程序有一个课程页面和一个添加新课程页面。单击 Add New Course 时出现错误:System.Reflection.TargetInvocationException - 调用目标抛出异常.我不知道自己做错了什么,并且花了 10 多个小时试图解决这个问题。有没有更好的方法来导航到所需的页面?
对于项目的要求,我仅限于使用 Pie 9.0 - API 28 在 Android 上运行
课程页面.xaml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:viewmodels="clr-namespace:FinalTestProject.ViewModels"
xmlns:model="clr-namespace:FinalTestProject.Models"
x:Class="FinalTestProject.Views.CoursesPage"
Title="{Binding Title}">
<ContentPage.BindingContext>
<viewmodels:CoursesModel/>
</ContentPage.BindingContext>
<ContentPage.ToolbarItems>
<ToolbarItem Text="Add New Course" Command="{Binding NavigateToAddNewCoursePageCommand}"/>
</ContentPage.ToolbarItems>
<ListView
BackgroundColor="Transparent"
CachingStrategy="RecycleElement"
HasUnevenRows="True"
IsPullToRefreshEnabled="True"
ItemsSource="{Binding Course}"
IsRefreshing="{Binding IsBusy, Mode=OneWay}"
RefreshCommand="{Binding RefreshCommand}"
RefreshControlColor="Red"
SelectionMode="None"
SeparatorVisibility="None">
<ListView.ItemTemplate>
<DataTemplate x:DataType="model:Course">
<ViewCell>
<ViewCell.ContextActions>
<MenuItem/>
</ViewCell.ContextActions>
<Grid Padding="10">
<Frame CornerRadius="20" HasShadow="True">
<StackLayout>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
</Grid>
<Button Text="Delete" WidthRequest="100" Grid.Column="1"></Button>
<Label FontSize="Medium"
Grid.Column="0"
Text="{Binding CourseId}"/>
<Label FontSize ="Small"
Text="{Binding CourseName}"/>
<Label FontSize="Small"
Text="{Binding InstructorFirstName}"/>
<Label FontSize="Small"
Text="{Binding InstructorLastName}"/>
<Label FontSize="Small"
Text="{Binding AssessmentType}"/>
</StackLayout>
</Frame>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
添加新课程页面.xaml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:viewmodels="clr-namespace:FinalTestProject.ViewModels"
x:DataType="viewmodels:AddNewCourseModel"
x:Class="FinalTestProject.Views.AddNewCoursePage"
Title="{Binding Title}">
<ContentPage.BindingContext>
<viewmodels:AddNewCourseModel/>
</ContentPage.BindingContext>
<ContentPage.Content>
<ScrollView>
<StackLayout Spacing="3" Padding="15">
<Label Text="Course Name" FontSize="Small"/>
<Entry Text="{Binding CourseName, Mode=TwoWay}" FontSize="Small"/>
<Label Text="Instructor's First Name" FontSize="Small"/>
<Entry Text="{Binding InstructorFirstName, Mode=TwoWay}" FontSize="Small"/>
<Label Text="Instructor's Last Name" FontSize="Small"/>
<Entry Text="{Binding InstructorLastName, Mode=TwoWay}" FontSize="Small"/>
<Label Text="Notes" FontSize="Small"/>
<Editor Text="{Binding Notes, Mode=TwoWay}" FontSize="Small" AutoSize="TextChanges"/>
<Label Text="Start Date" FontSize="Small"/>
<DatePicker Date="{Binding CourseStartDate}"/>
<Label Text="End Date" FontSize="small"/>
<DatePicker Date="{Binding CourseEndDate}"/>
<Label Text="Assessment Type" FontSize="Small"/>
<Picker BindingContext="{Binding }">
<Picker.Items>
<x:String>Objective</x:String>
<x:String>Performance</x:String>
</Picker.Items>
</Picker>
<StackLayout Orientation="Horizontal">
<Button Text="Save" Command="{Binding AddCourseCommand}" HorizontalOptions="FillAndExpand"></Button>
<Button Text="Cancel" Command="{Binding CancelCommand}" HorizontalOptions="FillAndExpand"></Button>
</StackLayout>
</StackLayout>
</ScrollView>
</ContentPage.Content>
课程模型.cs
public class CoursesModel : BaseViewModel
{
public ObservableRangeCollection<Course> AllCourses { get; set; }
public AsyncCommand RefreshCommand { get; }
public AsyncCommand NavigateToAddNewCoursePageCommand { get; }
public CoursesModel()
{
Title = "Courses";
AllCourses = new ObservableRangeCollection<Course>();
RefreshCommand = new AsyncCommand(Refresh);
NavigateToAddNewCoursePageCommand = new AsyncCommand(NavigateToAddNewCoursePage);
}
async Task NavigateToAddNewCoursePage()
{
await Shell.Current.GoToAsync(nameof(AddNewCoursePage));
}
async Task Refresh()
{
Busy();
AllCourses.Clear();
var courses = await CourseService.GetAllCourses();
AllCourses.AddRange(courses);
NotBusy();
}
}
添加新课程模型
公共类 AddNewCourseModel : BaseViewModel { 私人字符串课程名称;
public AsyncCommand AddCourseCommand { get; }
public AsyncCommand CancelCommand { get; }
public AddNewCourseModel()
{
Title = "Add New Course";
AddCourseCommand = new AsyncCommand(AddCourse);
CancelCommand = new AsyncCommand(Cancel);
}
async Task AddCourse()
{
var course = new Course()
{
CourseName = CourseName
};
await CourseService.AddCourse(course);
await Shell.Current.GoToAsync("CoursesPage");
}
async Task Cancel()
{
await Shell.Current.GoToAsync("CoursesPage");
}
public string CourseName
{
get => courseName;
set => SetProperty(ref courseName, value);
}
}
添加新课程页面.xaml.cs
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class AddNewCoursePage : ContentPage
{
public AddNewCoursePage()
{
InitializeComponent();
}
}
AppShell.xaml.cs
public partial class AppShell : Xamarin.Forms.Shell
{
public AppShell()
{
InitializeComponent();
Routing.RegisterRoute(nameof(CoursesPage), typeof(CoursesPage));
Routing.RegisterRoute(nameof(AddNewCoursePage), typeof(AddNewCoursePage));
Routing.RegisterRoute(nameof(TermsPage), typeof(TermsPage));
Routing.RegisterRoute(nameof(AddNewTermPage), typeof(AddNewTermPage));
}
}
【问题讨论】:
-
你应该做的第一件事是寻找嵌套将显示抛出的原始异常的异常。使用
Exception.InnerException属性 - 或者只记录整个异常,它应该在那里。 -
您需要查看
InnerException属性以获取有关错误根本原因的更多详细信息 -
每个
InnerException都设置为(null)。 @JonSkeet 当你说“记录整个异常”时你是什么意思?我该怎么做?请原谅我的初级知识:) -
我不记得了每一个看到带有 null InnerException 的
TargetInvocationException。 “记录整个异常”是指记录调用ToString的结果。这应该包括任何嵌套的异常。 -
@JonSkeet 深入了解后,我能够查看内部异常。我得到的错误是
Cannot implicitly convert "small" to 'double'。如果你看看我的添加新课程页面.xaml上面的页面,你可以看到<Label Text="End Date" FontSize="small"/>的字符串小的是小写,其余是大写。在为此花费了 10 多个小时后,我希望有更好的 xaml 错误记录方法。我很高兴这是一个简单的修复,但对缺少错误记录感到失望。感谢您帮助查看内部异常。