2016-02-20 3 views
0

Я новичок в WPF, и я бы хотел, чтобы TreeView отображал значок разворота/свернуть (треугольник рядом с узлом) во все времена, независимо от того, есть ли в нем элементы.WPF TreeView не перерисовывается

Чтобы показать это в любое время, добавить фиктивный элемент для узлов, которые не имеют элементов, оканчивающиеся с чем-то, как показано ниже (на данный момент, я хотел бы сделать это в коде, сзади):

+ Node 1 
- Node 2 
- Dummy Item 
+ Node 3 

Дополнительным требованием является удаление Dummy Item после того, как узел, имеющий его, будет расширен.
Чтобы сделать это, я удалить элемент в OnExpand:

public void OnExpand(object sender, EventArgs e) 
{ 
    ... 
    foreach (var item in tvItems){ 
     if (item is dummy){ 
      tvItems.Children.Remove(item); 
     } 
    } 
    ... 
} 

Проблема с этим состоит в том, что когда-то узел расширяется, я вижу пустую строку

+ Node 1 
- Node 2 
      <-- How to remove this line? 
+ Node 3 

Как удалить эту строку так, чтобы список показывает, как:

+ Node 1 
    Node 2 // there is no empty line btw Node 2 and Node 3 
+ Node 3 

ответ

1

попробовать этот образец

<Window x:Class="TreeViewExample.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="350" Width="525"> 
<Grid> 
    <Grid.Resources> 
     <HierarchicalDataTemplate x:Key="ChildTemplate" > 
      <TextBlock FontStyle="Italic" Text="{Binding Path=Name}" /> 
     </HierarchicalDataTemplate> 
     <HierarchicalDataTemplate x:Key="NameTemplate" ItemsSource="{Binding Path=Books}" 
            ItemTemplate="{StaticResource ChildTemplate}" > 
      <TextBlock Text="{Binding Path=Name}" FontWeight="Bold" /> 
     </HierarchicalDataTemplate> 
    </Grid.Resources> 
    <TreeView HorizontalAlignment="Left" Height="218" VerticalAlignment="Top" Width="175" Margin="76,37,0,0" ItemsSource="{Binding Standards}" ItemTemplate="{StaticResource NameTemplate}" x:Name="tv" TreeViewItem.Expanded="TreeViewItem_Expanded"  /> 

</Grid> 

Вот MainWindow.cs

using System.Collections.ObjectModel; 
using System.Windows; 
using System.Windows.Controls; 

namespace TreeViewExample 
{ 
/// <summary> 
/// Interaction logic for MainWindow.xaml 
/// </summary> 
public partial class MainWindow : Window 
{ 
    ObservableCollection<Author> authors = new ObservableCollection<Author>(); 

    public ObservableCollection<Author> Standards 
    { 
     get { return authors; } 
     set { authors = value; } 
    } 
    public MainWindow() 
    { 
     InitializeComponent(); 
     this.Loaded+=MainWindow_Loaded; 
     this.DataContext = this; 
    } 
    void MainWindow_Loaded(object sender, RoutedEventArgs e) 
    { 
     ObservableCollection<Book> Books = new ObservableCollection<Book>(); 
     Books.Add(new Book() { Id = 1, Name = "X" }); 
     Books.Add(new Book() { Id = 2, Name = "Y" }); 
     Books.Add(new Book() { Id = 3, Name = "Z" }); 

     ObservableCollection<Book> Books2 = new ObservableCollection<Book>(); 
     Books2.Add(new Book() { Id = 1, Name = "X" }); 
     Books2.Add(new Book() { Id = 2, Name = "Y" }); 
     Books2.Add(new Book() { Id = 3, Name = "Z" }); 


     Standards.Add(new Author() { Name = "I", Books = Books }); 
     Standards.Add(new Author() { Name = "II" }); 
     Standards.Add(new Author() { Name = "III", Books = Books2 }); 
    } 

    private void TreeViewItem_Expanded(object sender, RoutedEventArgs e) 
    { 
     TreeViewItem tvi = e.OriginalSource as TreeViewItem; 
     Author author = tvi.Header as Author; 
     author.Books.Clear(); 

    } 
} 

public class Author 
{ 
    public string Name { get; set; } 
    public ObservableCollection<Book> Books { get; set; } 
} 
public class Book 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 
} 

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

1

Самый простой способ - переопределить шаблон по умолчанию, чтобы отключить скрытие индикатора. К сожалению, вы не можете сделать это с помощью двух строк кода XAML, но это все еще легко.

Во-первых, вам нужно получить default TreeView template и скопировать его в свой ресурсный словарь. Если у вас нет словаря стилей, вы можете создать новый и поместить все там (сначала кисти, затем все стили).

Во-вторых, вам нужно найти триггер, который скрывает кнопку и удалить его (или изменения IsEnabled или что вы хотите):

<Trigger Property="HasItems" 
     Value="false"> 
    <Setter TargetName="Expander" 
      Property="Visibility" 
      Value="Hidden" /> 
</Trigger> 

В-третьих, мы должны дать основной стиль наш собственный ключ, так что x:Key="{x:Type TreeView}" будет, например, x:Key="CustomTreeViewStyle". И использовать его для нашего TreeView:

<Window.Resources> 
    <ResourceDictionary> 
     <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary Source="MyTreeViewStyles.xaml" /> 
     </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary> 
</Window.Resources> 


<Grid> 
    <TreeView Style="{StaticResource CustomTreeViewStyle}" /> 
</Grid> 

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

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