c# - MVVM + 多级/嵌套数据绑定(bind)

标签 c# windows-phone-7 data-binding mvvm windows-phone-8

结构

场景是我有一个数据透视表,其中每个项目都是某一天的菜单。在该 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

我有以下 View 模型

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

应实现所需布局(结构)的 View 如下:

<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>

如您所见,有嵌套数据绑定(bind)来获取所需的数据。

我在页面上执行的唯一代码是

DataContext = App.ViewModel;

问题

当我启动它时,我得到了数据透视项标题中显示的正确数据以及数据透视项的正确数量。不幸的是,就是这样; PivotItem 的内容保持为空。因此,第一级数据绑定(bind)有效,但仅此而已。

我的想法

  • 第一级:每个 PivotItem 链接到 Menu 类型的对象,标题为 Menu.Date
  • 第二级:在 PivotItem 内,我将 ItemsControl 的 ItemsSource 设置为 Menu.Categories
  • 第 3 级:ItemsSource 现在是 Menu.Categories.Dishes

我已经搜索了很多,并摆弄了 Datacontext 和 ItemsSource 以及不同类型的“{Binding ...}”,但我无法让它工作。我想在 xaml 中进行绑定(bind),而不是在代码隐藏中。

注释

  • 唯一的功能是显示数据。数据是固定的,并且从文件中加载一次。 这就是为什么我选择 ItemsControl 而不是 ListBox,不需要选择任何内容。
  • 这是针对我之前问题的 MVVM 方法:Databinding + Dynamic Pivot

最佳答案

首先,您尝试访问标题中的私有(private)字段,因此这是行不通的。这些也必须是属性,而不是字段。

<TextBlock Text="{Binding Date}" />

private string Date;

接下来,您将绑定(bind)到 Category,它也是私有(private)的,而不是属性。

<TextBlock Text="{Binding Category}"/>

private string Category;

您要绑定(bind)到“类别”字段,该字段需要是一个属性。

<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>

关于c# - MVVM + 多级/嵌套数据绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14012593/

相关文章:

c# - 我想创建自己的虚拟打印机,当打印发生时它会弹出我的应用程序

c# - 由于 'missing' 引用,无法构建发布配置

windows-phone-7 - 获取windows phone 7的当前IP

windows-7 - 多点触控桌面设备的经济选择(在 Windows Phone 7 模拟器上测试应用程序)?

windows-phone-7 - 如何在Windows Phone 8 中获取MCC 和MNC

c# - 如何在XAML中在Window之前声明资源?

c# - 除非我先清理/重建解决方案,否则 Visual Studio 2012 不会应用更改

c# - 使用内部联接执行 SQL 更新

data-binding - 将可见性绑定(bind)到 knockout 中的表达式

c# - 使用通用列表作为数据源和自动生成列的 Gridview