2

I have a TreeView that I'm binding to an observable collection, which has two observable collections inside of it:

Public Class ocSpecialPolicies
    Implements INotifyPropertyChanged
    Public Event PropertyChanged(sender As Object, e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
    Protected Overridable Sub OnPropertyChanged(ByVal Propertyname As String)
        If Not Propertyname.Contains("Changed") Then
            Changed = True
        End If
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(Propertyname))
    End Sub

    Private _changed As Boolean
    Public Property Changed() As Boolean
        Get
            Return _changed
        End Get
        Set(ByVal value As Boolean)
            If _changed <> value Then
                _changed = value
                OnPropertyChanged("Changed")
            End If
        End Set
    End Property

    Public Property Items As New ObservableCollection(Of ocSpecialPoliciesItem)
    Public Property Explanations As New ObservableCollection(Of ocSpecialPoliciesExplain)

    Private _RecallNum As String
    Public Property RecallNum As String
        Get
            Return _RecallNum
        End Get
        Set(value As String)
            If _RecallNum <> value Then
                _RecallNum = value
                OnPropertyChanged("RecallNum")
            End If
        End Set
    End Property
End Class

I have it half working:

<TreeView Name="TreeView2" Margin="3" ItemsSource="{Binding ElementName=MainWindow, Path=SpecialPolicies, UpdateSourceTrigger=PropertyChanged}">
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Path=Items, UpdateSourceTrigger=PropertyChanged}">
            <TextBlock Text="{Binding Path=RecallNum}" >
            </TextBlock>
            <HierarchicalDataTemplate.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Path=LaborOp}" >
                    </TextBlock>
                </DataTemplate>
            </HierarchicalDataTemplate.ItemTemplate>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

Where I'm able to see the RecallNum Property, and the Items Property, but I'm having trouble figuring out how to also show the Explanations as additional child nodes under RecallNum.

Ideally, it would look something like this:

RecallNum*
    Items
        LaborOp
        LaborOp
        LaborOp**
    Explanations
        *ExplanationText
        **ExplanationText

I've tried HierarchicalDataTemplate in TreeView.Resources, but I'm just not doing something right. Binding is something I've always had a hard time wrapping my head around.

Community
  • 1
  • 1
AndyD273
  • 7,177
  • 12
  • 54
  • 92

1 Answers1

3

I don't know if this will work in the context, and I can't try it right now, but what about...

        <HierarchicalDataTemplate.ItemTemplate>
            <DataTemplate TargetType="{x:Type=ocSpecialPoliciesItem}">
              ...
            </DataTemplate>
            <DataTemplate TargetType="{x:Type=ocSpecialPoliciesExplain}">
              ...
            </DataTemplate>
        </HierarchicalDataTemplate.ItemTemplate>

Or something along those lines?

EDIT: On the understanding that we want a single TreeView that has two sorts of item (sorry, this is c#, but I'm sure you can translate).

You can try making a base class, from which you derive both ocSpecialPoliciesItem and ocSpecialPoliciesExplain, and make an observable collection of the base class. Then use two DataTemplates in your TreeView.

class SpecialPoliciesBase {}

class ocSpecialPoliciesItem : SpecialPoliciesBase 
{ ... }

class ocSpecialPoliciesExplain : SpecialPoliciesBase
{ ... }

class ocSpecialPolicies
{
     // this is where you put ocSpecialPoliciesItem  and 
     // ocSpecialPoliciesExplain
     // I do not see any code for populating your two collections, 
     // but I suppose you must have some somewhere
   public ObersvableCollection<SpecialPoliciesBase> SPCollection
   { get ... }
}

And in your XAML

<TreeView 
  Name="TreeView2" 
  Margin="3" 
  ItemsSource="{
    Binding ElementName=MainWindow, 
    Path=SPCollection, 
    UpdateSourceTrigger=PropertyChanged}">

  <TreeView.ItemTemplate>
    <HierarchicalDataTemplate ...>
       <TextBlock Text="{Binding Path=RecallNum}" />

       <HierarchicalDataTemplate.ItemTemplate>
           <DataTemplate TargetType={x:Type ocSpecialPoliciesItem} > 
               <!- this is where you put the template for Item !->
           </DataTemplate>
           <DataTemplate TargetType={x:Type: ocSpecialPoliciesExplain} > 
               <!- this is where you put the template for Explanations !->
           </DataTemplate>
        </HierarchicalDataTemplate.ItemTemplate>
    </HierarchicalDataTemplate>
</TreeView.ItemTemplate>

I have something like this working, but not with a treeview. I use an empty abstract ViewBase class, with several concrete View classes. My ViewModel has a Property called CurrentView, of type ViewBase, and there is a DataTemplate for each of the concrete views. My XAML picks out the right DataTemplate for whichever derived class CurrentView has.

PScr
  • 449
  • 2
  • 11
  • Honestly, I'm not sure how to do that... You'll see in my half working example, that I have TreeView2 bound to the SpecialPolicies ObservableCollection Property, and then the HierarchicalDataTemplate bound to the Item Property. It's the only way I've been able to get it to work. I think I need to pull SpecialPolicies.RecallNum out of that HierarchicalDataTemplate so I can nest sub items, but don't know how. I really wish there was a way to view/debug the databinding in the UI view, as right now I feel like I'm just guessing and stumbling in the dark. – AndyD273 Oct 05 '15 at 14:51
  • Ah, re-reading, I probably misunderstood, anyway. I think you want to display the ocSpecialPoliciesItem at one level of the hierarchy, and then ocSpecialPoliciesExplain one level deeper. Doest every -Item have an -Explain? – PScr Oct 05 '15 at 15:02
  • Not every one. And as the data tables are set up the explanation and items are not explicitly linked, since it's possible to have an explanation without an item (it could be an explanation of the special policy itself instead of on an item...). Short version, I have to treat them as two different children types of SpecialPolicy, instead of child/grandchild... – AndyD273 Oct 05 '15 at 15:09
  • So you want the Items all first, with their LaborOp, then the Explanations afterwards, and you want all this in one control? That is what you get from your last edit. I'm going to suggest something in an edit of my own. – PScr Oct 06 '15 at 07:13