Как установить ItemsSource для списка в виде списка, используя рекурсивный объект в качестве основного источника данных? - PullRequest
0 голосов
/ 11 октября 2018

Решено доброй душой, которая заставила меня понять, что мне нужно более тщательно отладить. Код, который я здесь привожу, на самом деле работает.

Я пытался обернуть голову вокруг этогов течение нескольких дней это сначала казалось легким, но я не смог заставить его работать.

У меня есть объект, который содержит коллекцию самого себя:

public class Car: ViewModelBase 
{ 
    private string _name;
    public string Name { get { return _name; } set { Set(ref _name, value); } }

    private ObservableCollection<Car> _carCollection = new ObservableCollection<Car>();
    public ObservableCollection<Car> CarCollection { get { return _carCollection; } set { Set(ref _carCollection, value); } }
}

В моей ViewModelЯ определяю экземпляр объекта:

public class RecipesViewModel:ViewModelBase
{
    private Car _car; 
    public Car Car  { get { return _car; } set { Set(ref _car, value); } }

    //User populates the name prop and the list within car (level 1 data), 
   //and adds a number of objects to the list within the level 1 list  (level 2 data)
}

В представлении / XAML я создал список с Itemtemplate и источником данных:

<Page
x:Class="CarProject.Views.CarPage"
DataContext="{Binding CarViewModel, Source={StaticResource Locator}}"
...
mc:Ignorable="d">

<Page.Resources>
    <ResourceDictionary>
        <CollectionViewSource Source="{x:Bind ViewModel.Car.CarCollection, Mode=OneWay}" 
                              x:Key="CarListSource" 
                              IsSourceGrouped="False"/>
    </ResourceDictionary>
</Page.Resources>

<Grid>
<ListView x:Name="CarList"
          ItemsSource ="{Binding Source={StaticResource RecipeSingleAromaListSource}, Mode=OneWay}" >
    <ListView.ItemTemplate>
          <DataTemplate x:DataType="models:Car" x:Name="CarItem" >
               <StackPanel>
                  <TextBlock Text="{x:Bind Name}"/>
                  <ListView x:Name="Level2Sublist"
                            ItemsSource="{Binding CarCollection"}>
                       <ListView.ItemTemplate>
                            <DataTemplate>
                                 <TextBlock Text="{Binding Name}"/>
                            </DataTemplate>
                       </ListView.ItemTemplate>
               </StackPanel>
         </DataTemplate>
    </ListView.ItemTemplate>    
 </ListView>
</Grid>

Я перепробовал множество перестановок RelativeSource и ItemsSourceопределения для "Level2SubList", но я не могу сослаться на коллекцию автомобилей level2.«Level2SubList» остается пустым, независимо от того, что я делаю.

Я искал в Интернете и не нашел аналогичного варианта использования.Возможно, мне нужен урок по использованию Google, потому что я не могу быть единственным, кто попробовал это:)

Спасибо!

PS Класс и список XAML содержат множество других свойств,Я упростил это для удобства чтения

1 Ответ

0 голосов
/ 11 октября 2018

Внутренний DataTemplate не имеет атрибута x:DataType, который требуется, если вы используете x:Bind:

<DataTemplate x:DataType="models:Car">
   ...
</DataTemplate>

А затем, чтобы фактически показать Name автомобиля, выИспользуем Name свойство TextBlock, но это фактически устанавливает Имя XAML.Вам необходимо свойство Text:

<TextBlock Text="{x:Bind Name}" />

Обновление

Помимо этих проблем, код работает для меня.Попробуйте следующее в пустом проекте UWP (имя шахты App3):

MainPage.xaml

<Page
    x:Class="App3.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App3"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid>
        <ListView x:Name="CarList"
        ItemsSource="{x:Bind Car.CarCollection}" >
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="local:Car" x:Name="CarItem" >
                    <StackPanel>
                        <TextBlock Text="{x:Bind Name}"/>
                        <ListView x:Name="Level2Sublist"
                        ItemsSource="{Binding CarCollection}">
                            <ListView.ItemTemplate>
                                <DataTemplate>
                                    <TextBlock Text="{Binding Name}"/>
                                </DataTemplate>
                            </ListView.ItemTemplate>
                        </ListView>
                    </StackPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</Page>

MainPage.xaml.cs

using System.Collections.ObjectModel;
using Windows.UI.Xaml.Controls;

namespace App3
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }


        public Car Car { get; } = new Car()
        {
            CarCollection = new ObservableCollection<Car>()
            {
                new Car(){Name = "A", CarCollection = new ObservableCollection<Car>(){ new Car(){Name="A1"}, new Car(){Name="A2" } } },
                new Car(){Name = "B", CarCollection = new ObservableCollection<Car>(){ new Car(){Name="B1"}, new Car(){Name="B2" }, new Car(){Name="B3" } }}
            }
        };
    }

    public class Car
    {
        public string Name { get; set; }

        public ObservableCollection<Car> CarCollection { get; set; }
    }
}

Приложение отображает даже вложенный список:

App

...