ObservableCollection с ObservableCollections не рендерится правильно - PullRequest
2 голосов
/ 05 октября 2010

Я относительно новичок в Silverlight и пытаюсь создать приложение MVVM с DomainService, которое возвращает POCO в качестве моделей.У меня есть UserControl, который имеет TreeView с ItemsSource, установленным для привязки к ObservableCollection типа, который имеет ObservableCollection в качестве одного из своих свойств, и эта коллекция имеет тип, который имеет свойство ObservableCollection.Поэтому я использую HierarchicalDataTemplate в качестве ItemTemplate TreeView с TextBlocks для визуализации свойства 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. Добавляет каждый экземпляр соответствующим образом с LINQ через циклы foreach.И возвращает список.Метод работает правильно, как я назвал его из default.aspx.cs, и пошагово прошел, чтобы подтвердить, что все данные добавлены правильно.

Но моя проблема в том, что когда он отображается на экране, ни одна из коллекций не является правильной.Например, первый элемент дочерней коллекции «A» «B» должен иметь число более 4000, но ни один из них не отображается.И все же, первый элемент «B», который должен находиться в коллекции «Bs» первого «A», показан для второго элемента «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

После некоторого исследования я вижу только одну модель: иерархия основана на одинаковом идентификаторе.

Вот примеры кода:

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

ViewModel

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 - Silverlight 4 - VisualStudio 2010

Ответы [ 2 ]

1 голос
/ 05 октября 2010

У меня сложилось впечатление, что HierarchicalDataTemplate используется иерархически :) То есть вы используете one only , и это рекурсивно применяется к любым дочерним элементам.

Это означает, что ключи данных должны быть связаны, а данные унифицированы (того же типа).

Шаблон, который вы описали выше, в основном вкладывает 3 шаблона друг в друга, поэтому вы получаете первую запись каждого из отображаемых (где есть дочерние данные).

0 голосов
/ 05 октября 2010

Я думаю, что вы должны обязательно учесть одну вещь - заставить объекты реализовывать 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")

Это будет означать, что свойство было обновлено.

...