UI 在 xamarin 中用于行数可变的项目
UI in xamarin for items with variable number of rows
假设我有以下 类:
class Person
{
public string Name { get; set; }
public IList<Expense> Expenses { get; set; }
public int Total => Expenses.Sum(o => o.Amount);
}
class Expense
{
public string ExpenseName { get; set; }
public int Amount { get; set; }
}
然后我有一组人:IList<Person> Persons
如何在 Xamarin 中设计一个 XAML 页面,以便显示这样的内容?:
在您的 DataTemplate 中,您可以添加另一个支持 ItemSource 的视图 属性。
因此它可能是另一个 ListView、CollectionView 或 StackLayout。如果您知道您不会有太多费用项目,那么后者非常有用,否则它可能会导致严重的应用程序性能问题。
所以在你的数据模板中添加
<CollectionView ItemSource={Binding Expenses}>
<DataTemplate>
//your UI goes here
.
.
.
可以使用Label来显示可变的费用数目,在item末尾加"\n"包起来。
运行截图如下图
首先,这是我的布局。
<StackLayout>
<ListView x:Name="EmployeeView" HasUnevenRows="True"
ItemsSource="{Binding Persons}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Label FontSize="Large" Text="{Binding Name}"></Label>
<Label FontSize="Body" Text="{Binding ExpensesList}"></Label>
<Label FontSize="Body" Text="{Binding Total}"></Label>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
这里是布局的后台代码。
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
this.BindingContext =new MyViewModel();
}
}
这是我的视图模型。我在viewModel中添加了一些测试数据,并在每笔费用的文本末尾添加了“\n”。
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace App83
{
internal class MyViewModel
{
public ObservableCollection<Person> Persons { get; set; }
public MyViewModel()
{
Persons = new ObservableCollection<Person>();
ObservableCollection<Expense> expenses= new ObservableCollection<Expense>();
expenses.Add(new Expense() { Amount=1, ExpenseName="name1" });
expenses.Add(new Expense() { Amount = 1, ExpenseName = "name2" });
expenses.Add(new Expense() { Amount = 1, ExpenseName = "name3" });
expenses.Add(new Expense() { Amount = 1, ExpenseName = "name4" });
ObservableCollection<Expense> expenses2 = new ObservableCollection<Expense>();
expenses2.Add(new Expense() { Amount = 1, ExpenseName = "name1" });
ObservableCollection<Expense> expenses3 = new ObservableCollection<Expense>();
string expensesList1="";
for (int i = 0; i < expenses.Count; i++)
{
if(i== (expenses.Count - 1))
{
expensesList1 += expenses[i].ToString();
}
else
{
expensesList1 += expenses[i].ToString() + "\n";
}
}
string expensesList2 = "";
for (int i = 0; i < expenses2.Count; i++)
{
if (i == (expenses2.Count - 1))
{
expensesList2 += expenses2[i].ToString();
}
else
{
expensesList2 += expenses2[i].ToString() + "\n";
}
}
string expensesList3 = "";
for (int i = 0; i < expenses3.Count; i++)
{
if (i == (expenses3.Count - 1))
{
expensesList3 += expenses3[i].ToString();
}
else
{
expensesList3 += expenses3[i].ToString() + "\n";
}
}
Person per =new Person( ) { Name="test1", Expenses= expenses, expensesList= expensesList1 };
Person per2 = new Person() { Name = "test2", Expenses = expenses2,expensesList= expensesList2 };
Person per3 = new Person() { Name = "test3", Expenses = expenses3, expensesList = expensesList3 };
Persons.Add(per);
Persons.Add(per2);
Persons.Add(per3);
}
}
}
这是我编辑的模型。添加ExpensesList
perperty显示可变数量的费用,保持ExpenseName
和Amount
在同一行,我重写了ToString
方法。
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
namespace App83
{
public class Person: INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public Person() {
}
public string Name { get; set; }
public string expensesList;
public string ExpensesList
{
set
{
if (expensesList != value)
{
expensesList = value;
OnPropertyChanged("Image");
}
}
get
{
return expensesList;
}
}
public IList<Expense> Expenses { get; set; }
public int Total => Expenses.Sum(o => o.Amount);
}
public class Expense
{
public string ExpenseName { get; set; }
public int Amount { get; set; }
public override string ToString()
{
return ExpenseName+" "+Amount;
}
}
}
假设我有以下 类:
class Person
{
public string Name { get; set; }
public IList<Expense> Expenses { get; set; }
public int Total => Expenses.Sum(o => o.Amount);
}
class Expense
{
public string ExpenseName { get; set; }
public int Amount { get; set; }
}
然后我有一组人:IList<Person> Persons
如何在 Xamarin 中设计一个 XAML 页面,以便显示这样的内容?:
在您的 DataTemplate 中,您可以添加另一个支持 ItemSource 的视图 属性。
因此它可能是另一个 ListView、CollectionView 或 StackLayout。如果您知道您不会有太多费用项目,那么后者非常有用,否则它可能会导致严重的应用程序性能问题。
所以在你的数据模板中添加
<CollectionView ItemSource={Binding Expenses}>
<DataTemplate>
//your UI goes here
.
.
.
可以使用Label来显示可变的费用数目,在item末尾加"\n"包起来。
运行截图如下图
首先,这是我的布局。
<StackLayout>
<ListView x:Name="EmployeeView" HasUnevenRows="True"
ItemsSource="{Binding Persons}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Label FontSize="Large" Text="{Binding Name}"></Label>
<Label FontSize="Body" Text="{Binding ExpensesList}"></Label>
<Label FontSize="Body" Text="{Binding Total}"></Label>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
这里是布局的后台代码。
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
this.BindingContext =new MyViewModel();
}
}
这是我的视图模型。我在viewModel中添加了一些测试数据,并在每笔费用的文本末尾添加了“\n”。
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace App83
{
internal class MyViewModel
{
public ObservableCollection<Person> Persons { get; set; }
public MyViewModel()
{
Persons = new ObservableCollection<Person>();
ObservableCollection<Expense> expenses= new ObservableCollection<Expense>();
expenses.Add(new Expense() { Amount=1, ExpenseName="name1" });
expenses.Add(new Expense() { Amount = 1, ExpenseName = "name2" });
expenses.Add(new Expense() { Amount = 1, ExpenseName = "name3" });
expenses.Add(new Expense() { Amount = 1, ExpenseName = "name4" });
ObservableCollection<Expense> expenses2 = new ObservableCollection<Expense>();
expenses2.Add(new Expense() { Amount = 1, ExpenseName = "name1" });
ObservableCollection<Expense> expenses3 = new ObservableCollection<Expense>();
string expensesList1="";
for (int i = 0; i < expenses.Count; i++)
{
if(i== (expenses.Count - 1))
{
expensesList1 += expenses[i].ToString();
}
else
{
expensesList1 += expenses[i].ToString() + "\n";
}
}
string expensesList2 = "";
for (int i = 0; i < expenses2.Count; i++)
{
if (i == (expenses2.Count - 1))
{
expensesList2 += expenses2[i].ToString();
}
else
{
expensesList2 += expenses2[i].ToString() + "\n";
}
}
string expensesList3 = "";
for (int i = 0; i < expenses3.Count; i++)
{
if (i == (expenses3.Count - 1))
{
expensesList3 += expenses3[i].ToString();
}
else
{
expensesList3 += expenses3[i].ToString() + "\n";
}
}
Person per =new Person( ) { Name="test1", Expenses= expenses, expensesList= expensesList1 };
Person per2 = new Person() { Name = "test2", Expenses = expenses2,expensesList= expensesList2 };
Person per3 = new Person() { Name = "test3", Expenses = expenses3, expensesList = expensesList3 };
Persons.Add(per);
Persons.Add(per2);
Persons.Add(per3);
}
}
}
这是我编辑的模型。添加ExpensesList
perperty显示可变数量的费用,保持ExpenseName
和Amount
在同一行,我重写了ToString
方法。
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
namespace App83
{
public class Person: INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public Person() {
}
public string Name { get; set; }
public string expensesList;
public string ExpensesList
{
set
{
if (expensesList != value)
{
expensesList = value;
OnPropertyChanged("Image");
}
}
get
{
return expensesList;
}
}
public IList<Expense> Expenses { get; set; }
public int Total => Expenses.Sum(o => o.Amount);
}
public class Expense
{
public string ExpenseName { get; set; }
public int Amount { get; set; }
public override string ToString()
{
return ExpenseName+" "+Amount;
}
}
}