WPF树视图未重新绘制
我是WPF新手,我希望TreeView始终显示展开/折叠图标(节点旁边的三角形),而不管节点中是否有项 为了在任何时候都显示它,我为没有项目的节点添加了一个虚拟项目,这些项目的结尾类似于以下内容(现在,我想在代码隐藏中这样做): 进一步的要求是,一旦扩展了具有虚拟项的节点,就删除该虚拟项。WPF树视图未重新绘制,wpf,treeview,Wpf,Treeview,我是WPF新手,我希望TreeView始终显示展开/折叠图标(节点旁边的三角形),而不管节点中是否有项 为了在任何时候都显示它,我为没有项目的节点添加了一个虚拟项目,这些项目的结尾类似于以下内容(现在,我想在代码隐藏中这样做): 进一步的要求是,一旦扩展了具有虚拟项的节点,就删除该虚拟项。 为此,我删除OnExpand中的项: public void OnExpand(object sender, EventArgs e) { ... foreach (var item in t
为此,我删除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
试试这个样品
<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; }
}
}
使用System.Collections.ObjectModel;
使用System.Windows;
使用System.Windows.Controls;
名称空间树示例
{
///
///MainWindow.xaml的交互逻辑
///
公共部分类主窗口:窗口
{
ObservableCollection作者=新ObservableCollection();
公共可观测收集标准
{
获取{返回作者;}
设置{authors=value;}
}
公共主窗口()
{
初始化组件();
this.Loaded+=主窗口\u Loaded;
this.DataContext=this;
}
已加载无效主窗口(对象发送器、路由目标)
{
ObservableCollection Books=新的ObservableCollection();
Books.Add(newbook(){Id=1,Name=“X”});
Books.Add(newbook(){Id=2,Name=“Y”});
Books.Add(newbook(){Id=3,Name=“Z”});
ObservableCollection Books2=新的ObservableCollection();
Books2.Add(newbook(){Id=1,Name=“X”});
Books2.Add(newbook(){Id=2,Name=“Y”});
Books2.Add(newbook(){Id=3,Name=“Z”});
添加(新作者(){Name=“I”,Books=Books});
添加(新作者(){Name=“II”});
添加(新作者(){Name=“III”,Books=Books2});
}
私有void树视图项已展开(对象发送方,路由目标)
{
TreeViewItem tvi=e.原始来源为TreeViewItem;
Author=tvi.Header作为作者;
author.Books.Clear();
}
}
公共类作者
{
公共字符串名称{get;set;}
公共可观测收集簿{get;set;}
}
公共课堂用书
{
公共int Id{get;set;}
公共字符串名称{get;set;}
}
}
此示例为节点加载示例数据,无论何时尝试展开该项,都会清除子项。
让我知道这可以解决您的问题。试试这个示例
<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; }
}
}
使用System.Collections.ObjectModel;
使用System.Windows;
使用System.Windows.Controls;
名称空间树示例
{
///
///MainWindow.xaml的交互逻辑
///
公共部分类主窗口:窗口
{
ObservableCollection作者=新ObservableCollection();
公共可观测收集标准
{
获取{返回作者;}
设置{authors=value;}
}
公共主窗口()
{
初始化组件();
this.Loaded+=主窗口\u Loaded;
this.DataContext=this;
}
已加载无效主窗口(对象发送器、路由目标)
{
ObservableCollection Books=新的ObservableCollection();
Books.Add(newbook(){Id=1,Name=“X”});
Books.Add(newbook(){Id=2,Name=“Y”});
Books.Add(newbook(){Id=3,Name=“Z”});
ObservableCollection Books2=新的ObservableCollection();
Books2.Add(newbook(){Id=1,Name=“X”});
Books2.Add(newbook(){Id=2,Name=“Y”});
Books2.Add(newbook(){Id=3,Name=“Z”});
添加(新作者(){Name=“I”,Books=Books});
添加(新作者(){Name=“II”});
添加(新作者(){Name=“III”,Books=Books2});
}
私有void树视图项已展开(对象发送方,路由目标)
{
TreeViewItem tvi=e.原始来源为TreeViewItem;
Author=tvi.Header作为作者;
author.Books.Clear();
}
}
公共类作者
{
公共字符串名称{get;set;}
公共可观测收集簿{get;set;}
}
公共课堂用书
{
公共int Id{get;set;}
公共字符串名称{get;set;}
}
}
此示例为节点加载示例数据,无论何时尝试展开该项,都会清除子项。
让我知道这可以解决您的问题。最简单的方法是覆盖默认模板以禁用隐藏指示器。不幸的是,用两行XAML代码无法做到这一点,但仍然很容易 首先,您需要获取并将其复制到资源字典中。如果你没有样式字典,你可以创建一个新的,把所有的东西都放在那里(先刷,然后是所有的样式) 其次,您需要找到隐藏按钮的触发器并将其删除(或更改为IsEnabled或任何您想要的): 就这样。不是最短的解决方案,而是一个简单的解决方案,您可以按自己喜欢的方式进行自定义。而且您不需要创建幻影项目
您可以在App.xaml中引用此词典,以便每个页面都可以使用它(如果需要)。此外,我在这里使用了
MergedDictionary
,以防页面中已经有一些资源-它们将进入ResourceDictionary本身。最简单的方法是覆盖默认模板以禁用隐藏指示符。不幸的是,用两行XAML代码无法做到这一点,但仍然很容易
首先,您需要获取并将其复制到资源字典中。如果你没有样式字典,你可以创建一个新的,把所有的东西都放在那里(先刷,然后是所有的样式)
其次,您需要找到隐藏按钮的触发器并将其删除(或更改为IsEnabled或任何您想要的):
就这样。不是最短的解决方案
<Trigger Property="HasItems"
Value="false">
<Setter TargetName="Expander"
Property="Visibility"
Value="Hidden" />
</Trigger>
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="MyTreeViewStyles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<TreeView Style="{StaticResource CustomTreeViewStyle}" />
</Grid>