在 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 以执行此操作的最佳实践是什么?
有很多方法可以解决这个问题。最简单的可能是使用包含 Label
的 ViewCell
和 Spans
而不是 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
在 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 以执行此操作的最佳实践是什么?
有很多方法可以解决这个问题。最简单的可能是使用包含 Label
的 ViewCell
和 Spans
而不是 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