2016-02-20 60 views
0

我是WPF的新手,我希望TreeView始终显示展开/折叠图标(节点旁边的三角形),而不管节点中是否有项目。WPF TreeView不重绘

要在任何时候都表现出来,我想补充一个虚拟项目适用于具有类似下面结束了没有项目节点(现在,我想在做这个代码隐藏):

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

进一步的要求是删除虚拟物品,一旦具有它的节点被展开。
要做到这一点,我删除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中进行。