tags:

views:

343

answers:

2

Hi

I am trying to make a tree list view that displays different information compared to the parent.

From what i have now, the Children display the same information as the parent. I was wondering, how i would do this. The last post i had didn't really quite make sense to me, it didn't work really well. I was wondering if anyone can explain this a little more in depth for me.

This is the last post

http://stackoverflow.com/questions/1745155/hierarchical-data-structure-wpf-treelistview

 <r:TreeListView x:Name="TimeSheetsTreeListView" Margin="0,-18.312,0,0" Style="{DynamicResource TreelistStyle}"  Width="Auto" MinHeight="150" 
                        Grid.Row="0" Background="#00FFFFFF" ItemsSource="{Binding TimeSheetItems, Mode=Default}" HorizontalContentAlignment="Center"
                        VerticalAlignment="Top" Height="207.446" Foreground="White" Grid:GridViewSort.AutoSort="True" >

                     <r:TreeListView.Columns>

                     <GridViewColumn  DisplayMemberBinding="{Binding ClientMatterName}" Width="200" 
                         Grid:GridViewSort.PropertyName="ClientMatterName" >

      <GridViewColumnHeader HorizontalContentAlignment="Center" Foreground="White" Content="Client Name/Matter Name" Grid:GridViewSort.PropertyName="ClientMatterName" FontSize="10.667"/>
      </GridViewColumn>

      <GridViewColumn  DisplayMemberBinding="{Binding ClientMatterCode}" Width="200" Grid:GridViewSort.PropertyName="ClientMatterCode" >
       <GridViewColumnHeader HorizontalContentAlignment="Center" Foreground="White" Content="Client No./Matter No." FontSize="10.667"/>
      </GridViewColumn>

      <GridViewColumn DisplayMemberBinding="{Binding TimeCode.Code}" Width="100" Grid:GridViewSort.PropertyName="TimeCodeCode" >
      <GridViewColumnHeader HorizontalContentAlignment="Center" Foreground="White" Content="Time Code" FontSize="10.667"/>

      </GridViewColumn>

      <GridViewColumn Header="Hours" Width="100" Grid:GridViewSort.PropertyName="Hours">
      <GridViewColumn.CellTemplate>
       <DataTemplate>
                              <TextBlock HorizontalAlignment="Left" Text="{Binding Duration, Converter={StaticResource BillableHoursConverter}}" />
                          </DataTemplate>
      </GridViewColumn.CellTemplate>   
      </GridViewColumn>

      <GridViewColumn Width="300" DisplayMemberBinding="{Binding Description}" Grid:GridViewSort.PropertyName="Description">
       <GridViewColumnHeader HorizontalContentAlignment="Center" Foreground="White" Content="Description" FontSize="10.667"/>
      </GridViewColumn>
     </r:TreeListView.Columns>

                            <r:TreeListView.Resources>

                                <HierarchicalDataTemplate DataType="{x:Type data:TimeSheet}" ItemsSource="{Binding Path= TimeRecords}">

                                </HierarchicalDataTemplate>    


                            </r:TreeListView.Resources>

                        </r:TreeListView>

A: 

your problem stems from the fact that both your parent and children are of the same type. the same template is used for both, what you need here is a data structure that is hierarchical.

if you had a parent task that had a collection of children and the children were of a different type than the parent then you would be cool. (because you could provide a different template for the children than the parent)

the other way to do it is to build a view model, with two different types, one for task overviews and one for sub tasks.

however i have found a hack solution using triggers based on collection sizes (when count is 0, i assume it is a leaf node) a better way would be to have a property on the object which states which type it is, parent or child, something you could easily do with a view model, or you could put the property on your business objects. go here and download the TreeViewTest.zip sample solution.

The above project is not an ideal solution. I create the view model every time. it gives you flexibility and control beyond what you have in straight wpf.

the project contains this code which is the tricky bit (note the string format on the bindings, they are really cool)

      <HierarchicalDataTemplate
        DataType="{x:Type local:Assignment}"
        ItemsSource="{Binding Path=AssignmentCollection}">
        <Grid>
           <TextBlock
           x:Name="parentTextBox">
           <TextBlock.Text>
              <MultiBinding
                 StringFormat="{}{0} - {1} - {2:F2}">
                 <Binding
                    Path="ClientName" />
                 <Binding
                    Path="Task" />
                 <Binding
                    Path="Hours" />
              </MultiBinding>
           </TextBlock.Text>    
        </TextBlock>
           <TextBlock
           x:Name="childTextBox" Visibility="Collapsed">
           <TextBlock.Text>
              <MultiBinding
                 StringFormat="{}{0:hh:mm tt} - {1:hh:mm tt} /{2}">
                 <Binding
                    Path="StartTime" />
                 <Binding
                    Path="EndTime" />
                 <Binding
                    Path="SubTask" />
              </MultiBinding>
           </TextBlock.Text>    
        </TextBlock>
        </Grid>
        <!--this is the trigger that chooses which text box to display-->
        <HierarchicalDataTemplate.Triggers>
           <DataTrigger
              Binding="{Binding AssignmentCollection.Count}"
              Value="0">
              <Setter
                 TargetName="parentTextBox"
                 Property="Visibility"
                 Value="Collapsed" />
              <Setter
                 TargetName="childTextBox"
                 Property="Visibility"
                 Value="Visible" />
           </DataTrigger>
        </HierarchicalDataTemplate.Triggers>
     </HierarchicalDataTemplate>
Aran Mulholland
This is what i haveI have a observableCollection Parentunder the parent i have a observable Collection Children.I want to have the children to display different stuff than the parent, but i can't seem to get that working.Any idea?
Kevin
SO it's basically in c#I haveparent[0].clientName;parent[0].Task;parent[0].child[0].StartTime;parent[0].child[0].EndTime;so in the above, i am trying to display the initial treelistviewwith the client name and the task associated with it.The children that are displayed will display the start time and end time of that task.
Kevin
Oh also, i forgot to saythe parent observable collection is information.and the child is a type detailsuch asobservablecollection<information> parent = new ObservableCollection<information>;observablecollection<detail> child = new ObservableCollection<detail>;
Kevin
+2  A: 

if you want to display a parent-child relationship in a treeview. (only one level deep, so the children are all leaf nodes). you bind the treeview to the collection of parent elements. then you do a hierarchical data template for the parent, and a standard data template for the child

in the example you give you have a Parent of object type information with a collection of children object type detail and the collection of detail (children) on the parent is called child

so we do a template for the children, and then one for the parent

  <!--Child (detail) DataTemplate-->
  <DataTemplate
     DataType="{x:Type local:detail}">
     <TextBox Text="{Binding Path=Some child binding}"/>
  </DataTemplate>

  <!--Parent (information) Hierarchical Template-->
  <HierarchicalDataTemplate
     DataType="{x:Type local:information}"
     ItemsSource="{Binding Path=Child}">
     <TextBox Text="{Binding Path=Some parent binding}"/>
  </HierarchicalDataTemplate>

because the parent and child are of a different object type, the tree view will grab the parent template, which has an items source and when it comes to draw the children it will use th child data template. note none of the data templates have keys, they are keyed on their object type.

Aran Mulholland
I am doing a treeListView, not a treeview. a tree list view is one with a lot of columns, not just a single column like the treeview. i still am not able to get this working for some reason.
Kevin
if you are creating your own control that has the same columns for the parent and the children then you must have the same fields on the parent and the children. or are you trying to do different columns for the parents and the children?
Aran Mulholland
I have two classes.One class called Information. One class called DetailI have three different columns.One saids Client, task, Description.Under those the parent will be named by client, task and description.For every client, you have a childunder client it will say "Start time"under task it will say end timeand under Description it will say total hours
Kevin