1
votes

I have already implemented a TreeView and have populated it using a CollectionViewSource bound to an ObserableCollection in the view model. (Code Below)

Can someone help me understand how it would be possible for me to bind the checkbox IsChecked property to a property on the ViewModel of the collection at the second level of the tree view.

I am trying to create the situation where if a child items is checked then the parent node is also checked and vise versa.

I think the main problem is that i dont know how to manipulate the items unless they are on the leaf node else I have no access to that Items collection in the parent levels..

Also is there a way that I can bind the CollectionViewSource's Source and use thouse items to bind to ?

Any tips, or code samples is appreciated

CollectionViewSource

 <CollectionViewSource x:Key="CSV"
                              Source="{Binding TestApplications}">
            <CollectionViewSource.SortDescriptions>
                <scm:SortDescription PropertyName="BaseAppName" />
                <scm:SortDescription PropertyName="Category" />
                <scm:SortDescription PropertyName="AppName" />
            </CollectionViewSource.SortDescriptions>
            <CollectionViewSource.GroupDescriptions>
                <PropertyGroupDescription PropertyName="BaseAppName" />
                <PropertyGroupDescription PropertyName="Category" />
            </CollectionViewSource.GroupDescriptions>

DataTemapltes

 <DataTemplate x:Key="AppNameTemplate">
            <StackPanel Orientation="Horizontal">
                <CheckBox IsChecked="{Binding Path=IsChecked, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                          IsEnabled="True"
                          IsThreeState="False"
                          Name="btnChecked">

                <i:Interaction.Triggers>                    
                        <i:EventTrigger EventName="Checked">
                            <i:InvokeCommandAction    Command="{Binding RelativeSource= {RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path= DataContext.SelectedTestAppChangedCommand}"/>                      
                        </i:EventTrigger>
                        <i:EventTrigger EventName="Unchecked">
                            <i:InvokeCommandAction    Command="{Binding RelativeSource= {RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path= DataContext.SelectedTestAppChangedCommand2}"/>
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                </CheckBox>

                <TextBlock Text="{Binding AppName}"
                           FontWeight="Bold">
                </TextBlock>
            </StackPanel>   
        </DataTemplate>

        <HierarchicalDataTemplate x:Key="CategoryTemplate"
                                  ItemsSource="{Binding Path=Items}"
                                  ItemTemplate="{StaticResource AppNameTemplate}">
            <StackPanel Orientation="Horizontal">
                <CheckBox IsChecked="{Binding RelativeSource= {RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeViewItem},AncestorLevel=2}, Path=IsChecked, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                          IsEnabled="True"
                          IsThreeState="False"
                          Name="btnChecked">
                </CheckBox>

                <TextBlock Text="{Binding Name}"
                           FontStyle="Italic">
                </TextBlock>
            </StackPanel>
        </HierarchicalDataTemplate>

        <HierarchicalDataTemplate x:Key="BaseAppTemplate"
                                  ItemsSource="{Binding Path=Items}"
                                  ItemTemplate="{StaticResource CategoryTemplate}">
            <TextBlock Text="{Binding Name}" />
        </HierarchicalDataTemplate>

TreeView

treeview has the following source and template:

ItemsSource="{Binding Source={StaticResource CSV}, Path=Groups}"
                                                         ItemTemplate="{StaticResource BaseAppTemplate}"

More Detail

ReadOnly Property TestApplications As ObservableCollection(Of ToolBaseModel)

** BaseModel**

Public Class ToolBaseModel
        Inherits NotificationObject
 Public Property Key As String
            Get
                Return mstrKey
            End Get
            Set(value As String)
                mstrKey = value
                Me.RaisePropertyChanged(Function() Me.AppName)
            End Set
        End Property

        Public Property Value As String
            Get
                Return mstrValue
            End Get
            Set(value As String)
                mstrValue = value
                Me.RaisePropertyChanged(Function() Me.Value)
            End Set
        End Property

        Public Property BaseAppName As String
            Get
                Return mstrConfgiFileName
            End Get
            Set(value As String)
                mstrConfgiFileName = value
                Me.RaisePropertyChanged(Function() Me.BaseAppName)
            End Set
        End Property

        Public Property Category As String
            Get
                Return mstrKey.Split(":"c).First
            End Get
            Set(value As String)
                mstrCategory = value
                Me.RaisePropertyChanged(Function() Me.Category)
            End Set
        End Property

        Public Property IsChecked() As Boolean
            Get
                Return mblnIsChecked
            End Get
            Set(ByVal value As Boolean)
                Me.RaisePropertyChanged(Function() Me.IsChecked)
            End Set
        End Property

        Public Property AppName As String
            Get
                Return mstrKey.Split(":"c)(1)
            End Get
            Set(value As String)
                mstrKey = value
                Me.RaisePropertyChanged(Function() Me.AppName)
            End Set
        End Property

        Public Property IsSelected() As Boolean
            Get
                Return mblnIsSelected
            End Get
            Set(ByVal value As Boolean)
                mblnIsSelected = value
                IsChecked = mblnIsSelected
                Me.RaisePropertyChanged(Function() Me.IsSelected)
            End Set
        End Property
EndClass
1
Can you show us the data structure bound to the CVS? Also, try and exemplify that "bound to the second level" requirement. I don't get if it's absolute or relative to the node. - Gabriel Rainha
@GabrielRainha - edited the question - AltF4_

1 Answers

1
votes

It looks like that binding on the second level template is not quite right.

See this representation of your tree:

--BaseAppTemplate

----CategoryTemplate {Binding ... AncestorLevel=2} Bad!

--------AppNameTemplate {Binding IsChecked} Good!

You see, AncestorLevel=n will look upwards for the n'th parent of the bound item. Checking you tree structure, there is no TreeViewItem 2 levels on top of CategoryTemplate, so that binding is probably failing (try and debug that one on the Output Windows)

Well, that's an error on your DataTemplate, but I still don't understand what you're trying to accomplish, so if you could provide a good visual sample (like that lame tree I've drawn) it would be great.