在 Xamarin.Forms 中,以纯文本显示来自视图模型的列表的最简单方法是什么?

In Xamarin.Forms, what is the simples way to display a list from a viewmodel in plain text?

在 Xamarin.Forms 应用程序中。我想让一个视图以纯文本形式显示来自 ViewModel 的对象列表。我见过使用这样的列表视图的示例。

<ListView x:Name="ItemView"
          ItemsSource="{Binding Items}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <TextCell Text="{Binding Text}"/>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

此方法似乎可行,但它不允许我在 TextCell 中使用多个对象 属性。 Visual Studio 2019 生成的示例应用程序使用 CollectionView 来做一些更复杂的事情。

<CollectionView x:Name="ItemsListView"
                ItemsSource="{Binding Items}"
                SelectionMode="None">
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <StackLayout Padding="10" x:DataType="model:Item">
                <Label Text="{Binding Name}" 
                       LineBreakMode="NoWrap" 
                       Style="{DynamicResource ListItemTextStyle}" 
                       FontSize="16" />
                <Label Text="{Binding Description}" 
                       LineBreakMode="NoWrap"
                       Style="{DynamicResource ListItemDetailTextStyle}"
                       FontSize="13" />
                <StackLayout.GestureRecognizers>
                    <TapGestureRecognizer 
                        NumberOfTapsRequired="1"
                        Command="{Binding Source={RelativeSource AncestorType={x:Type local:ItemsViewModel}}, Path=ItemTapped}"     
                        CommandParameter="{Binding .}">
                    </TapGestureRecognizer>
                </StackLayout.GestureRecognizers>
            </StackLayout>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

不过,此方法似乎不适用于我当前的 ViewModel。仅使用现有代码作为示例,我做了如下所示的内容。

Student.cs

public class Student
{
    public string Id { get; set; }
    public string Name { get; set; }
    public ICollection<Course> Courses{ get; set; }
}

Course.cs

public class Course
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string CourseNumber { get; set; }
}

StudentDetailViewModel.cs

[QueryProperty(nameof(StudentId), nameof(StudentId))]
public class StudentDetailViewModel : BaseViewModel
{
    private string studentId;
    private string name;
    private ICollection<Courses> courses;

    public string Id { get; set; }

    public string Name
    {
       get => name;
       set => SetProperty(ref name, value);
    }

    public ICollection<Course> Courses
    {
            get => Courses;
            set => SetProperty(ref courses, value);
    }

    public string StudentId
    {
        get
        {
            return studentId;
        }
        set
        {
            studentId = value;
            LoadStudentId(value);
        }
    }

    public async void LoadStudentId(string sId)
    {
        try
        {
            var student = await DataStore.GetItemAsync(sId);
            Id = student.Id;
            Name = student.Name;
            Courses = student.Courses;
        }
        catch (Exception)
        {
            Debug.WriteLine("Failed to Load Item");
        }
    }
}

我希望生成的页面显示类似

的内容
Student Name
Courses:
   * CourseNumber - CourseName
   * CourseNumber - CourseName
   * CourseNumber - CourseName

但是,当我尝试使用 ListView 方法时,我不知道如何格式化 TextCell 的 Text="{Binding PropName}" 属性 以便我可以在这个 "{ Prop1} - {Prop2}”格式。使用 CollectionView,我完全不知道如何正确绑定数据以显示它。显示此类内容的最简单方法是什么?设置我的 ViewModel 以执行此操作的最佳实践是什么?

有很多方法可以解决这个问题。最简单的可能是使用包含 LabelViewCellSpans 而不是 TextCell。您也可以使用 CollectionView 做类似的事情,不需要使用 Cells

<ListView ItemsSource="{Binding Courses}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
              <Label>
                <Label.FormattedText>
                  <FormattedString>
                     <Span Text="{Binding Name}" />
                     <Span Text=" - " />
                     <Span Text="{Binding CourseNumber}" />
                  </FormattedString>
                <Label.FormattedText>
              </Label>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

学生信息可以放在课程之前的单独布局中,或者添加到课程的 ListView.Header