Конкретный список строк в одном TreeViewItem - PullRequest
0 голосов
/ 03 мая 2019

В настоящее время я копаюсь в WPF и у меня возникает следующая проблема:

Моя модель данных (см. Ниже) имеет иерархические данные в 3 слоя (файл, строка в файле, строка, разбитая на части). Это я хочу отобразить в TreeView на 2 уровнях, так что первый уровень - это файлы, а элементы второго уровня - это объединенные строки списка TextParts (отформатированные в соответствии со свойством IsMatch).

Итак, этот пример данных

{ fileA("filename1"): { 
    line1: { part1("text1", false), part2("text2", true), part3("text3", false) }, 
    line2: { part4("text4", false) } 
} }

должно выглядеть так:

  • filename1
    • text1 text2 text3
    • text4

(примечание: я использовал жирный шрифт и курсив вместо белого и желтого фона, используемого в моем xaml)

Я уже прочитал эту документацию MS, которая дала мне хороший толчок во всем этом вопросе. Я не уверен, что это можно сделать в xaml, или можно как-то сгенерировать шаблон в коде?

Моя модель данных:

class MyModel {
    public ObservableCollection<ResultFile> FileLines { get; }
}
class ResultFile {
    public ObservableCollection<ResultLine> Lines { get; }
    public string Name { get; set; }
}
class ResultLine {
    public ObservableCollection<ResultTextPart> TextParts { get; }
}
class ResultTextPart {
    public string Text { get; set; }
    public bool IsMatch { get; set; }
}

Xaml:

<TreeView x:Name="TvSearchResults">
    <TreeView.Resources>
        <HierarchicalDataTemplate DataType="{x:Type m:ResultFile}" ItemsSource="{Binding Lines}">
            <StackPanel Orientation="Horizontal"><TextBlock Text="{Binding Name}"/> <!-- ... --> </StackPanel>
        </HierarchicalDataTemplate>
        <DataTemplate DataType="{x:Type m:ResultLine}">
            <!-- how to display the list of ResultTextPart as single line ? -->
        </DataTemplate>
        <DataTemplate DataType="{x:Type m:ResultTextPart}">
            <TextBlock Text="{Binding Text}" Name="tviTextPart" />
            <DataTemplate.Triggers>
                <DataTrigger Binding="{Binding IsMatch}" Value="true">
                    <Setter Property="Background" TargetName="tviTextPart" Value="Yellow"/>
                </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>
    </TreeView.Resources>
</TreeView>

Ответы [ 2 ]

2 голосов
/ 03 мая 2019

По сути, это должно делать то, что вы просите.Хотя между текстом нет пробелов, вы можете добавить это с помощью конвертера или чего-то еще.Потенциально, даже удаляя целые ItemsControl и имея конвектор, беру собранные и выбрасываемые струны, я просто хотел оставить все это в xaml для вас.

<TreeView x:Name="TvSearchResults" Width="200" Margin="20" ItemsSource="{Binding Data.FileLines}">
<TreeView.ItemTemplate>
    <HierarchicalDataTemplate ItemsSource="{Binding Lines}">
        <TextBlock Text="{Binding Path=Name}"/>
        <HierarchicalDataTemplate.ItemTemplate>
            <DataTemplate>
                <ItemsControl ItemsSource="{Binding TextParts}">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <StackPanel Orientation="Horizontal"/>
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Text}">
                                <TextBlock.Style>
                                    <Style TargetType="TextBlock">
                                        <Style.Triggers>
                                            <DataTrigger Binding="{Binding Path=IsMatch}" Value="True">
                                                <Setter Property="FontWeight" Value="Bold"/>
                                            </DataTrigger>
                                        </Style.Triggers>
                                    </Style>
                                </TextBlock.Style>
                            </TextBlock>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </DataTemplate>
        </HierarchicalDataTemplate.ItemTemplate>
    </HierarchicalDataTemplate>    
</TreeView.ItemTemplate>
</TreeView>
1 голос
/ 03 мая 2019

Для простоты:

<DataTemplate DataType="{x:Type m:ResultLine}">
    <ItemsControl ItemsSource="{Binding TextParts}" >
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel Orientation="Horizontal"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>
</DataTemplate>

Так что все, что вам нужно, это на самом деле использовать ItemsControl и установить горизонтально ориентированную панель для этого контейнера.

...