【问题标题】:ObservableCollection with ObservableCollections not rendering correctly带有 ObservableCollections 的 ObservableCollection 无法正确呈现
【发布时间】:2011-04-21 09:56:19
【问题描述】:

我对 Silverlight 体验比较陌生,我正在尝试创建一个带有 DomainService 的 MVVM 应用程序,该应用程序将 POCO 作为模型返回。我有一个 UserControl,它有一个 TreeView,其 ItemsSource 设置为绑定到一个 ObservableCollection 类型,该类型具有 ObservableCollection 作为其属性之一,并且该集合属于具有 ObservableCollection 属性的类型。所以我使用 HierarchicalDataTemplate 作为带有 TextBlocks 的 TreeView 的 ItemTemplate 来呈现每个项目的 Name 属性。我将在下面包含一些代码。

所以类应该是这样的:

public class A
{
    public int ID { get; set; }
    public string Name { get; set; }
    public ObservableCollection<B> Bs { get; set; }
}

public class B
{
    public int ID { get; set; }
    public string Name { get; set; }
    public ObservableCollection<C> Cs { get; set; }
}

public class C
{
    public int ID { get; set; }
    public string Name { get; set; }
}

基本上,我的集合是从 DataRepository 中填充的,该方法使用获取 A、B 和 C 列表的方法。通过 foreach 循环使用 LINQ 适当地添加每个实例。并返回一个列表。该方法正常工作,因为我从 default.aspx.cs 调用它并逐步确认所有数据都已正确添加。

但我的问题是,当它在屏幕上呈现时,没有一个集合是正确的。例如,“A”的“B”子集合的第一项应该有超过 4000 的计数,但没有显示。然而,应该在第一个“A”的集合“Bs”中的“B”的第一个项目显示为“A”的第二个项目。

(应该是什么的例子)

  • a1

    • b1.1
      • c1.1.1
      • c1.1.2
      • c1.1.3
    • b1.2
      • c1.2.1
      • c1.2.2
  • a2

    • b2.4
      • c2.4.1
      • c2.4.2
      • c2.4.3
  • a3

    • b3.6
      • c3.6.1
      • c3.6.2
      • c3.6.3
  • a4

    • b4.8
      • c4.8.1
      • c4.8.2
      • c4.8.3

(显示的示例)

  • a1
  • a2
    • b2.2
      • c2.2.2
  • a3
  • a4
    • b4.4
      • c4.4.4

经过一番调查,我看到的唯一模式是层次结构基于相同的 ID。

以下是代码示例:

(DataContext 由 UserControl 资源设置)

<sdk:TreeView ItemsSource="{Binding Path=As}" >
 <sdk:TreeView.ItemTemplate>`  
  <sdk:HierarchicalDataTemplate ItemsSource="{Binding Path=Bs}">
   <TextBlock Text="{Binding Path=Name}" />
   <sdk:HierarchicalDataTemplate.ItemTemplate>
    <sdk:HierarchicalDataTemplate ItemsSource="{Binding Path=Cs}">
     <TextBlock Text="{Binding Path=Name}" />
     <sdk:HierarchicalDataTemplate.ItemTemplate>
      <sdk:HierarchicalDataTemplate ItemsSource="{Binding}">
       <TextBlock Text="{Binding Path=Name}" />
      </sdk:HierarchicalDataTemplate>
     </sdk:HierarchicalDataTemplate.ItemTemplate>
    </sdk:HierarchicalDataTemplate>
   </sdk:HierarchicalDataTemplate.ItemTemplate>
  </sdk:HierarchicalDataTemplate>
 </sdk:TreeView.ItemTemplate>
</sdk:TreeView>

视图模型

public class myViewModel
{
    private myDomainContext context = new myDomainContext();

    public ObservableCollection<A> As
    {
        get
        {
            LoadOperation<A> loadOp = context.Load(context.GetAsQuery());
            return new ObservableCollection<A>(loadOp.Entities);
        }
    }
}

对于这个问题的长度,我深表歉意,我希望不要这么含糊,并获得一些有用的建议。这个问题已经困扰我几天了,我已经准备好继续前进了。请帮助我摆脱困境。提前致谢。如果您有任何对我的 MVVM 知识有帮助的好的链接,我也将不胜感激。

我的环境是: - ASP.NET 4 - 银光 4 - VisualStudio 2010

【问题讨论】:

  • 感谢为 xaml 添加缩进的人。

标签: silverlight mvvm silverlight-4.0 hierarchicaldatatemplate domainservices


【解决方案1】:

我的印象是 HierarchicalDataTemplate 分层使用 :) 也就是说,您只使用 一个,它递归地适用于任何孩子。

这确实意味着数据键必须与数据统一(相同类型)相关。

你上面描述的模板基本上是3个模板相互嵌套,所以你得到每个显示的第一条记录(有子数据的地方)。

【讨论】:

  • 从我最近注意到的情况来看,您可能正在做某事。我开始阅读有关 ItemTemplateSelectors 的内容,这可能与让我这样做有关。
  • 在调查了我的问题几天后,我发现我的数据/集合已正确填充到服务器上。但是当DomainService被调用,DomainContext的LoadOperation完成加载后,有没有发现集合出错了。这就是为什么没有正确渲染的原因。因此,我将开始一个新线程,请求就此事提供帮助。我已将此标记为答案,因为这是事情的真相。我在滥用 HierarchicalDataTemplate。所以谢谢你的帮助。祝大家编码愉快。
【解决方案2】:

我认为您绝对应该考虑的一件事是让对象实现 INotifyPropertyChanged。看这个例子http://snipplr.com/view/13639/viewmodelbase-class/

在这种情况下,您必须稍微更改属性

private int _id;

public int Id
{
     get { return _id;}
     set { _id = value; NotifyChanged("Id");}
}

它不必在属性内。当您更新子集合时,例如 Bs,您可以调用 NotifyChanged("Bs")

这将表明该属性已更新。

【讨论】:

  • re NotifyChanged("Bs"):除非 Bs 列表本身被实际替换,否则 ObservableCollection 已经为自己的内容更改发送了更改通知。
  • 这是正确的,但如果您确实从 List、Queryable 或 Enumerable 生成 ObservableCollection,则应该注意这一点。
  • 不要听起来对你的 cmets 忘恩负义,但我认为你们错过了问题的背景。基本上答案是分层模板必须使用与我想要显示具有三种数据类型的树相同的数据类型。所以我的解决方案是我正在创建一个 HierarchicalTreeView,它将根据在原始 itemssource 集合中找到的集合添加新项目。我也会在这里粘贴我的课程,以防其他人遇到这种情况。另外,如果可能的话,我想获得一些关于课程的反馈。再次感谢 cmets。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-19
  • 2015-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多