侧边栏壁纸
博主头像
Tony's Blog博主等级

行动起来,coding

  • 累计撰写 83 篇文章
  • 累计创建 58 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录
c#

C# WPF树结构的懒加载

Tony
2024-02-20 / 0 评论 / 0 点赞 / 19 阅读 / 6581 字

本文链接: https://blog.csdn.net/lishuangquan1987/article/details/102744805

平时我们的WPF程序中用到的树结构都是一次性将后台数据绑定到前端,如果数据比较大或者数结构比较深,这样会耗费很长时间,而且耗费内存,我们有没有针对树结构比较深采取延迟加载的策略呢?

先写上我自己测试过的可以在展开子节点时去加载子节点代码:

本示例的数据源是从数据库读取,数据库有两张表:

2-kqpg.png

两个表的数据如下:

3-cicu.png

这两个表对应的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>

最后运行效果:

4-dsmi.png

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

0

评论区