Иерархическая структура данных WPF TreeListView DataTriggers - PullRequest
0 голосов
/ 18 ноября 2009

Я пытаюсь создать древовидный список, который отображает другую информацию по сравнению с родительским.

Исходя из того, что я имею сейчас, Дети отображают ту же информацию, что и родитель. Мне было интересно, как бы я это сделал. Последнее сообщение, которое я написал, не имело для меня никакого смысла, оно работало не очень хорошо. Мне было интересно, если кто-нибудь может объяснить это немного подробнее для меня.

Это последнее сообщение:

Иерархическая структура данных 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 ]

2 голосов
/ 19 ноября 2009

, если вы хотите отобразить родительско-дочерние отношения в виде дерева. (только один уровень глубины, поэтому все дочерние узлы листьев). Вы привязываете древовидное представление к коллекции родительских элементов. затем вы делаете иерархический шаблон данных для родительского элемента и стандартный шаблон данных для дочернего элемента

в приведенном вами примере у вас есть родительский объект типа информация с коллекцией дочерних объектов типа detail и коллекцией detail (children) на родителя называется ребенок

поэтому мы делаем шаблон для детей, а затем один для родителя

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

, поскольку родительский и дочерний объекты относятся к разным типам объектов, древовидное представление будет захватывать родительский шаблон, у которого есть источник элементов, и при рисовании дочерних элементов он будет использовать этот шаблон дочерних данных. обратите внимание, что ни один из шаблонов данных не имеет ключей, они имеют ключ к типу объекта.

0 голосов
/ 18 ноября 2009

Ваша проблема проистекает из того факта, что ваши родители и дети относятся к одному и тому же типу. один и тот же шаблон используется для обоих, здесь вам нужна иерархическая структура данных.

если бы у вас было родительское задание, в котором была коллекция детей, и дети были другого типа, чем родитель, то вы были бы крутыми. (потому что вы могли бы предоставить другой шаблон для детей, чем родитель)

другой способ сделать это - создать модель представления двух разных типов: один для обзоров задач и один для подзадач.

однако я нашел решение для взлома с использованием триггеров, основанных на размерах коллекции (когда count равен 0, я предполагаю, что это конечный узел), лучшим способом было бы иметь свойство объекта, указывающее, какой это тип, родительский или ребенок, то, что вы могли бы легко сделать с моделью представления, или вы могли бы поместить свойство в свои бизнес-объекты. перейдите сюда и загрузите образец решения 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...