1

I'm working with Catel, MVVM, WPF and am wondering about how to work with nested/hiearchical data.

Let's say from a database I've got a list of Customers, each with a list of Invoices, each with a list of InvoiceItems. Customers own many Invoices which own many InvoiceItems.

I've got a working solution, but I do not like it. My approach was to build a collection of classes that would act a kind of like an ado.net “dataset.” A class would represent each layer of the hiearchy.

This top level class, CustomerModel, would contain a collection of of InvoiceBlocks:

CustomerModel
ObservableCollection of < InvoicesBlocks >

Each InvoceBlock would contain an Invoice and a collection of InvoiceItems:

InvoiceBlock
Invoice
ObservableCollection of < InvoiceItems >

It seemed clever until wading through the databinding path= satements. There are also times when I have to loop through the sets mamaully to update totals, defeating a major selling point of MVVM.

So, I've decided to learn more about grouping with LINQ queries and databinding. Is this the way the pros do it?

4

1 回答 1

0

您可以做的是让每个视图模型负责使用正确的服务来检索数据。

请注意,我没有使用 Catel 属性来使其易于理解,但您可以简单地使用Catel.Fody或重写属性以获取 Catel 属性。

public class CustomerViewModel
{
    private readonly IInvoiceService _invoiceService;

    public CustomerViewModel(ICustomer customer, IInvoiceService invoiceService)
    {
        Argument.IsNotNull(() => customer);
        Argument.IsNotNull(() => invoiceService);

        Customer = customer;
        _invoiceService = invoiceService;
    }

    public ICustomer Customer { get; private set; }

    public ObservableCollection<IInvoice> Invoices { get; private set; }

    protected override void Initialize()
    {
        var customerInvoices = _invoiceService.GetInvoicesForCustomer(Customer.Id);
        Invoices = new ObservableCollection<IInvoice>(customerInvoices);
    }
}


public class InvoiceViewModel
{
    private readonly IInvoiceService _invoiceService;

    public InvoiceViewModel(IIinvoice invoice, IInvoiceService invoiceService)
    {
        Argument.IsNotNull(() => invoice);
        Argument.IsNotNull(() => invoiceService);

        Invoice = invoice;
        _invoiceService = invoiceService;
    }

    public IInvoice Invoice { get; private set; }

    public ObservableCollection<IInvoiceBlock> InvoiceBlocks { get; private set; }

    protected override void Initialize()
    {
        var invoiceBlocks = _invoiceService.GetInvoiceBlocksForInvoice(Invoice.Id);
        InvoiceBlocks = new ObservableCollection<IInvoiceBlock>(invoiceBlocks);
    }
}

现在你完全可以控制什么时候会发生什么。

于 2014-01-14T07:49:32.417 回答