首页 > 解决方案 > 如何在列表视图中设置列表视图的 ItemsSource,使用递归对象作为主要数据源?

问题描述

由一个善良的灵魂解决,他让我意识到我需要更彻底地调试。我在这里提出的代码确实有效。

几天来我一直试图解决这个问题,它最初看起来很容易,但我无法让它发挥作用。

我有一个包含自身集合的对象:

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>

我已经为“Level2SubList”尝试了许多相对源和 ItemsSource 定义的排列,但我似乎无法引用 level2 汽车集合。无论我做什么,“Level2SubList”都保持空白。

我一直在网上搜索并没有找到类似的用例。也许我需要上一堂使用谷歌的课程,因为我不是唯一一个尝试过这个的人:)

谢谢!

PS 类和 XAML 列表包含许多其他属性,为了便于阅读,我对其进行了简化

标签: uwpuwp-xaml

解决方案


内部DataTemplate没有x:DataType属性,如果您使用的是必需的x:Bind

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

然后,要实际显示Name汽车的名称,您使用的是 的Name属性TextBlock,但这实际上设置了 XAML 名称。你需要的Text财产:

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

更新

除了这些问题,代码对我有用。在一个空白的 UWP 项目中尝试以下操作(我的名字是App3):

主页.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; }
    }
}

您甚至可以看到应用程序显示嵌套列表:

应用程序


推荐阅读