分层数据结构WPF TreeListView DataTriggers

时间:2009-11-17 22:11:42

标签: c# wpf xaml treeview

我正在尝试创建一个树列表视图,显示与父项相比的不同信息。

根据我现在的情况,儿童显示与父母相同的信息。我在想,我该怎么做。我的最后一篇文章对我来说并没有多大意义,它的效果并不好。我想知道是否有人可以为我更深入地解释这一点。

这是最后一篇文章:

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>

2 个答案:

答案 0 :(得分:2)

如果要在树视图中显示父子关系。 (只有一级深,所以孩子都是叶子节点)。将treeview绑定到父元素的集合。然后你为父母做一个分层数据模板,为孩子做一个标准的数据模板

在示例中,您为对象提供了一个父类型信息,其中包含子对象类型详细信息的集合以及详细信息的集合父母的(孩子)被称为孩子

所以我们为孩子们做了一个模板,然后为父母做了一个模板

  <!--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>

因为父级和子级具有不同的对象类型,所以树视图将抓取父模板,该模板具有项目源,并且在绘制子项时它将使用子项数据模板。请注意,没有任何数据模板具有键,它们键入其对象类型。

答案 1 :(得分:0)

你的问题源于你的父母和孩子都是同一类型的事实。同时使用相同的模板,这里需要的是一个分层的数据结构。

如果你的父任务有一个子集合,而且孩子的类型与父母不同,那么你会很酷。 (因为您可以为子项提供与父项不同的模板)

另一种方法是构建一个视图模型,它有两种不同的类型,一种用于任务概述,另一种用于子任务。

但是我发现了一个使用基于集合大小的触发器的hack解决方案(当count为0时,我假设它是一个叶子节点)更好的方法是在对象上有一个属性,说明它是哪种类型,父级或者孩子,您可以轻松使用视图模型执行的操作,或者您可以将属性放在业务对象上。 go here并下载TreeViewTest.zip示例解决方案。

上述项目不是理想的解决方案。我每次都创建视图模型。它为您提供了超越wpf的灵活性和控制力。

项目包含这个代码,这是一个棘手的位(注意绑定上的字符串格式,它们真的很酷)

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