Вложение двух списков в форматах Xamarin не рекомендуется (или даже поддерживается, я думаю).
Лучшим способом, вероятно, будет использование сгруппированного ListView, связанного с вложенным ObservableCollection <T>. Здесь внешней коллекцией будет ObservableCollection <ViewModelA>. Каждый ViewModelA затем происходит от ObservableCollection <ViewModelB>. Так что это коллекция коллекций.
Кроме того, из-за вашего ViewModelB.Parent = некоторого требования к ViewModelA внутренние коллекции должны быть обновлены до нужного подмножества элементов ViewModelB (т. Е. С родителем == some ViewModelA), всякий раз, когда ваша плоская глобальная коллекция всех элементов ViewModelB изменения. Это потребует некоторой дополнительной логики в реализации ViewModelA.
Конкретно решение может быть следующим:
Сначала определяют три ViewModel классов (ViewModelMain, ViewModelA и ViewModelB) следующим образом:
ViewModelMain:
using System;
using System.Collections.ObjectModel;
using System.Windows.Input;
using Xamarin.Forms;
namespace XamLab1
{
public class ViewModelMain
{
public ObservableCollection<ViewModelA> AItems { get; set; }
public ObservableCollection<ViewModelB> AllBItems { get; set; }
public ViewModelMain()
{
AItems = new ObservableCollection<ViewModelA>();
AllBItems = new ObservableCollection<ViewModelB>();
this.UpdateCommand = new Command<string>((key) =>
{
Update();
});
}
public ICommand UpdateCommand { protected set; get; }
public void Update()
{
// filling collections with dummy test data...
AItems.Clear();
AllBItems.Clear();
for (int i = 0; i < 10; i++)
{
long timestamp = DateTime.Now.Ticks;
var a = new ViewModelA("A-" + i + "-" + timestamp, AllBItems);
AItems.Add(a);
for (int j = 0; j < 3; j++)
{
AllBItems.Add(new ViewModelB { NameB = "B-" + i + "-" + j + "-" + timestamp, Parent = a });
}
}
}
}
}
ViewModelA:
using System.Collections.ObjectModel;
using System.Linq;
namespace XamLab1
{
public class ViewModelA : ObservableCollection<ViewModelB>
{
public string NameA { get; private set; }
public ViewModelA(string name, ObservableCollection<ViewModelB> allBItems)
{
NameA = name;
_allBItems = allBItems;
_allBItems.CollectionChanged += _allBItems_CollectionChanged;
}
private ObservableCollection<ViewModelB> _allBItems;
private void _allBItems_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
ClearItems();
foreach (var item in _allBItems.Where(x => x.Parent == this))
{
Add(item);
}
}
}
}
и ViewModelB:
namespace XamLab1
{
public class ViewModelB
{
public string NameB { get; set; }
public ViewModelA Parent { get; set; }
}
}
Наконец, связать модели вида на XAML, как это:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:XamLab1;assembly=XamLab1"
x:Class="XamLab1.MainPage">
<ContentPage.BindingContext>
<local:ViewModelMain />
</ContentPage.BindingContext>
<StackLayout>
<Button Text="Update" Command="{Binding UpdateCommand}"></Button>
<ListView ItemsSource="{Binding AItems}" IsGroupingEnabled="True" GroupDisplayBinding="{Binding NameA}" GroupShortNameBinding="{Binding NameA}" HasUnevenRows="True">
<ListView.GroupHeaderTemplate>
<DataTemplate>
<ViewCell>
<StackLayout VerticalOptions="FillAndExpand" Padding="5" BackgroundColor="#707070">
<Label Text="{Binding NameA}"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.GroupHeaderTemplate>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout VerticalOptions="FillAndExpand" Padding="20, 5, 5, 5">
<Label Text="{Binding NameB}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
Теперь запустите полученное приложение и нажмите кнопку Update: вы должны увидеть ListView обновляются новыми данные ViewModel.
Обратите внимание: это решение может по-прежнему использовать некоторую оптимизацию. Например, вероятно, не очень эффективно обновлять все внутренние коллекции всякий раз, когда меняется коллекция глобальных BItems. Возможно, что-то вроде более ленивого обновления. Кроме того, если ваша коллекция AllBItems велика, вы можете рассмотреть некоторый механизм индексирования свойства Parent, чтобы ускорить фильтрацию.