首页 > 解决方案 > 在 Xamarin.Forms 中,以纯文本形式显示视图模型中的列表的最简单方法是什么?

问题描述

在 Xamarin.Forms 应用程序中。我想让 View 以纯文本形式显示 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。仅以现有代码为例,我制作了如下所示的内容。

学生.cs

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

课程.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 方法时,我不知道如何格式化Text="{Binding PropName}"TextCell 的属性,以便可以使用这种“{Prop1} - {Prop2}”格式的两个属性。使用 CollectionView,我根本不知道如何正确绑定数据以显示它。显示此类内容的最简单方法是什么,以及设置我的 ViewModel 以执行此操作的最佳实践是什么?

标签: c#xamarin.formsmvvm

解决方案


有很多方法可以解决这个问题。最简单的可能是使用包含ViewCellaLabelSpans不是 a TextCell。你也可以用 a 做类似的事情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


推荐阅读