MVVM +多级/嵌套数据绑定

本文关键字:嵌套 数据绑定 多级 MVVM | 更新日期: 2023-09-27 17:49:15

结构

这个场景是,我有一个Pivot,其中每个项目都是某一天的菜单。在PivotItem中,我需要显示菜单上的菜肴,按类别分组(例如,汤,甜点,…)。

我已经用mvvm模型实现了这个。

因此我有以下模型:

public class Menu{
    public string Date;
    public List<DishList> Categories;
}
public class DishList
{
    public string Category;
    public List<Dish> Dishes;
}
public class Dish
{
    public string Name;
    public string Price;
}

编辑:这里是简化的,每个字段的实际结构是这样的:

    private string _date;
    //Get_Set
    public string Date
    {
        get
        {
            return _date;
        }
        set
        {
            if (value != _date)
            {
                _date = value;
            }
        }
    }

结构应该是这样的:一个PivotElement包含一个菜单对象。在里面,我展示了"类别"和一些"菜单"。在这个菜品列表中,我显示了类别和不同的菜品,每个菜品都有名字和价格。一个让事情更清楚的模型(SkyDrive上的pdf文件);http://sdrv.ms/12IKlWd

我有以下视图模型

public class MenuViewModel : INotifyPropertyChanged
{
    private ObservableCollection<Menu> _Menus;
}

应该实现所需布局的视图(结构)如下:

<phone:Pivot 
        ItemsSource="{Binding Menus}">
        <phone:Pivot.HeaderTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Date}" />
            </DataTemplate>
        </phone:Pivot.HeaderTemplate>
        <phone:Pivot.ItemTemplate>
            <DataTemplate>
                <ItemsControl
                    ItemsSource="{Binding Categories}">   
                    <TextBlock
                        Text="{Binding Category}"/>
                    <ItemsControl
                        x:Name="Dishes"
                        ItemsSource="{Binding Dishes}">
                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <Grid>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="300"/>
                                        <ColumnDefinition Width="*"/>
                                    </Grid.ColumnDefinitions>
                                    <TextBlock 
                                        Grid.Column="1" 
                                        Text="{Binding Name}"/>
                                    <TextBlock 
                                        Grid.Column="2" 
                                        Text="{Binding Price}"/>
                                </Grid>
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ItemsControl>
                </ItemsControl>
            </DataTemplate>
        </phone:Pivot.ItemTemplate>
    </phone:Pivot>

正如您所看到的,有嵌套的数据绑定来获取所需的数据。

然后我在页面上做的唯一代码是

DataContext = App.ViewModel;
<标题>

当我启动它时,我得到正确的数据显示在PivotItems标题中,以及正确的PivotItems数量。不幸的是,仅此而已;透视item的内容保持空。因此,第一层数据绑定可以工作,但不能再工作了。

我的想法

  • 第一级:每个pivotiitem都链接到一个标题为Menu的类型的对象。
  • 第二级:在透视item中,我设置ItemsControl的ItemsSource为该菜单。
  • 第3级:ItemsSource现在是Menu.Categories.Dishes

我已经搜索了相当多的数据上下文和ItemsSource和不同类型的"{Binding…,但我不能让它工作。我想在xaml中做绑定,而不是在代码后面。

<标题> 指出
  • 唯一功能是显示数据。数据是固定的,只从文件中加载一次。这就是为什么我选择ItemsControl而不是ListBox,没有必要选择任何东西。
  • 这是一个mvvm方法来解决我之前的问题:数据绑定+动态枢轴

MVVM +多级/嵌套数据绑定

首先,您试图访问标题中的私有字段,因此无法正常工作。这些也必须是属性,而不是字段。

<TextBlock Text="{Binding Date}" />
private string Date;

接下来你要绑定到Category,它也是私有的,而不是一个属性。

<TextBlock Text="{Binding Category}"/>
private string Category;

你绑定到Categories字段它需要是一个属性。

<ItemsControl ItemsSource="{Binding Categories}">
public List<DishList> Categories;

即使你纠正了这些问题,你仍然不会得到你想要的,因为你的外部ItemsControl没有ItemTemplate

<ItemsControl ItemsSource="{Binding Categories}">   
  <TextBlock Text="{Binding Category}"/>
  ...
</ItemsControl>

添加:你的新错误是因为DataTemplate只能有一个子元素,所以你需要使用一个容器,如StackPanel

<ItemsControl ItemsSource="{Binding Categories}">
  <ItemsControl.ItemTemplate>
    <DataTemplate>
      <StackPanel Orientation="Horizontal">
        <TextBlock Text="{Binding Category}"/>
        <ItemsControl x:Name="Dishes" ItemsSource="{Binding Dishes}">
          ...
        </ItemsControl>
      </StackPanel>
     </DataTemplate>
   </ItemsControl.ItemTemplate>
</ItemsControl>