本文链接: https://blog.csdn.net/lishuangquan1987/article/details/102744805
平时我们的WPF程序中用到的树结构都是一次性将后台数据绑定到前端,如果数据比较大或者数结构比较深,这样会耗费很长时间,而且耗费内存,我们有没有针对树结构比较深采取延迟加载的策略呢?
先写上我自己测试过的可以在展开子节点时去加载子节点代码:
本示例的数据源是从数据库读取,数据库有两张表:

两个表的数据如下:

这两个表对应的C#实体类的结构:
public class TreeNode
{
public string TreeNodeName { get; set; }
public int TreeNodeId { get; set; }
public IEnumerable<TreeNode> Children { get; set; }
}
这里使用IEnumerable就是为了能够延迟加载数据
读取数据库数据的函数:
public IEnumerable<TreeNode> LoadTree()
{
var list = LoadSubTree(1);
return list;
}
public IEnumerable<TreeNode> LoadSubTree(int parentId)
{
string sql = "select TreeNodeID,TreeNodeName from TreeNodeRelationship left join TreeNodeInfo on TreeNodeInfo.TreeNodeID=TreeNodeRelationship.ChildrenId where ParrentId=@ParentId";
using (var conn = ConnectionFactory.GetConnection())
{
var list = conn.Query<TreeNode>(sql,new { ParentId=parentId});
foreach (var i in list)
{
i.Children = LoadSubTree(i.TreeNodeId);
yield return i;
}
}
}
贴出后台全部代码:
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
private IEnumerable<TreeNode> treeNodes;
public IEnumerable<TreeNode> TreeNodes
{
get { return treeNodes; }
set { treeNodes = value; }
}
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
}
public IEnumerable<TreeNode> LoadTree()
{
var list = LoadSubTree(1);
return list;
}
public IEnumerable<TreeNode> LoadSubTree(int parentId)
{
string sql = "select TreeNodeID,TreeNodeName from TreeNodeRelationship left join TreeNodeInfo on TreeNodeInfo.TreeNodeID=TreeNodeRelationship.ChildrenId where ParrentId=@ParentId";
using (var conn = ConnectionFactory.GetConnection())
{
var list = conn.Query<TreeNode>(sql,new { ParentId=parentId});
foreach (var i in list)
{
i.Children = LoadSubTree(i.TreeNodeId);
yield return i;
}
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
treeNodes = LoadTree();
//this.DataContext = null;
this.DataContext = TreeNodes;
}
}
读取数据库的数据用到了Dapper.
贴出前台代码:
<Window x:Class="LazyLoadingTreeView.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:LazyLoadingTreeView"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300"></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<TreeView ItemsSource="{Binding}">
<TreeView.Style>
<Style TargetType="TreeView">
<Setter Property="ItemTemplate">
<Setter.Value>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<TextBlock Text="{Binding TreeNodeName}"></TextBlock>
</HierarchicalDataTemplate>
</Setter.Value>
</Setter>
</Style>
</TreeView.Style>
</TreeView>
<Button Height="30" Width="150" Grid.Column="1" Click="Button_Click">加载Tree</Button>
</Grid>
</Window>
最后运行效果:

当展开树节点时再去读取树节点下的第一个子节点
评论区