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显示可变数量的费用,保持ExpenseNameAmount在同一行,我重写了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;
        }
    }
}