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:
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"
</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}"/>
</r:TreeListView.Resources>
</r:TreeListView>
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.
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>
精彩评论