2016-02-20 63 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中進行。