Question

I am relatively new to the Silverlight experience and am trying to create a MVVM app with a DomainService that returns POCOs as the models. I have a UserControl that has a TreeView with the ItemsSource set to bind to an ObservableCollection of a type that has an ObservableCollection as one of it's properties, and that collection is of a type that has a property of ObservableCollection. So I'm using the HierarchicalDataTemplate as the ItemTemplate of the TreeView with TextBlocks to render the Name property of each item. I will include some code below.

So the classes would be something like this:

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

Basically, my collections are getting populated from a DataRepository with a method that gets lists of A,B, and C. Adds each instance appropriately with LINQ through foreach loops. And returns a List. The method works correctly as I have called it from the default.aspx.cs and stepped through to confirm that all data is correctly added.

But my problem is that when it is rendered on the screen, none of the collections are correct. For instance, the first item of "A"'s child collection of "B" should have a count of over 4000 and yet none are shown. And yet, the first item of "B" that is supposed to be in the collection "Bs" of the first "A" is shown for the second item of "A".

(example of what it should be)

  • 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

(example of what it is showing)

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

After some investigation, the only pattern that I see is that the hierarchy is based on the ID's being the same.

Here are the code samples:

(the DataContext is set by a UserControl Resource)

<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);
        }
    }
}

I apologize about the length of this question, I was hoping to not be so vague and to get some helpful advise. This issue has been plaguing me for a few days now and I'm sooo ready to move on. Please help me get out of the muck. Thanks in advance. And if you have any good links that would be helpful for my MVVM knowledge I would greatly appreciate them as well.

My Environment is: - Asp.Net 4 - Silverlight 4 - VisualStudio 2010

Was it helpful?

Solution

I was under the impression that a HierarchicalDataTemplate is used hierarchically :) That is, you use one only and it recursively applies to any children.

This does mean that the data keys must be related and the data uniform (of the same type).

The template you have described above is basically nesting 3 templates inside each other, so you get the first record of each displayed (where there is child data).

OTHER TIPS

I think that one thing you should definitely consider is to make the objects implement the INotifyPropertyChanged. See this example http://snipplr.com/view/13639/viewmodelbase-class/

In that case you have to alter the properties a little bit

private int _id;

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

It doesn't have to be inside of a Property. When you update the child collection for instance the Bs you can call NotifyChanged("Bs")

This will signal that the property has been updated.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top