• TreeView数据的延迟加载


      使用TreeView时,很多人都应该遇到过当数据项特别多的时候,界面加载很慢的情况,用户体验很差,为了解决这个问题,这里我想到使用延时加载子项的方法去实现,即:我们显示的数据项,用户不一定所有项都很用到,初始化时,我们只加载根节点数据显示在界面,当展开根节点时,只加载根节点子项的数据,子项的子项数据不加载,依次类推,这样就解决了一次加载很多数据,界面初始化需要很长时间的问题。

      最近在看X女特工,感觉还可以,一个国家的成立需要牺牲很多人,其中也包括很多无辜的人,一份最终走到一起爱情也不是一天两天就可以,彼此都有许多苦衷,我觉得,最重要还是相互信任,不管对方做什么信任是很重要的,事实总会有一天浮出水面,结局也很好,没有吊人胃口,最终走到了一起,虽然很多枪战场面很假,毕竟消磨时间而已,无需计较,不过最后一集爆炸场面挺多的,看来要结局了,把能用的炸药都用了。

      我们同一时间终须去专心的去做某一项工作,当同时进行的任务多了,我们的效率反而会降低,我们大脑不是多核,不会并行计算,但合理的安排也会使我们提高工作效率的,休息的时候休息,玩的时候玩,工作的时候就专心工作,随心而做,就会倍感轻松。

      无聊的时候扯扯,空闲的时候扯扯,生活需扯,有扯的生活就不会太无聊,另外有期待的生活也会充满激情,比如等待一部电视剧的更新,比如期待的爱情。

      下面进入正题,如何实现数据的延时加载,这里我的思路的重新TreeViewItem项,定义一个事件,当TreeViewItem展开时触发加载事件,以下是我的代码实现,这里监听的TreeViewItem里面的ToggleButton单击事件

     public class TreeItemBase : TreeViewItem
        {
            static TreeItemBase()
            {
                DefaultStyleKeyProperty.OverrideMetadata(typeof(TreeItemBase), new FrameworkPropertyMetadata(typeof(TreeItemBase)));
            }
    
            public TreeItemBase()
            {
                this.Expanded += new RoutedEventHandler(TreeItemBase_Expanded);
            }
    
            public event Func<TreeItemBase, IEnumerable<TreeItemBase>> GetChidren;
    
            ToggleButton _ToggleButton = null;
    
            public override void OnApplyTemplate()
            {
                base.OnApplyTemplate();
                _ToggleButton = this.GetTemplateChild("Expander") as ToggleButton;
                _ToggleButton.Click += new RoutedEventHandler(TreeItemBase_Expanded);
            }
    
            void TreeItemBase_Expanded(object sender, RoutedEventArgs e)
            {
                var btn = sender as ToggleButton;
    
                if (this.GetChidren != null)
                {
                    //TODO:每次加载计算,或第一次加载计算
                    var childs = this.GetChidren(this);
                    if (childs.Count() != 0)
                    {
                        _ToggleButton.Visibility = System.Windows.Visibility.Visible;
                        this.BeginInit();
                        this.Items.Clear();
                        childs.ToList().ForEach(i => { this.Items.Add(i); });
                        this.EndInit();
                        if (btn != null)
                        {
                            this.IsExpanded = btn.IsChecked == true;
                        }
                    }
                    else//如果没有数据将Item前的button隐藏掉
                    {
                        if (_ToggleButton != null)
                        {
                            _ToggleButton.Visibility = System.Windows.Visibility.Collapsed;
                        }
                    }
                }
            }
    另外模板也有地方需要修改,就是IsChecked绑定IsExpanded属性否则,双击TreeViewItem加载数据事件不会触发
    <Setter Property="Control.Template">
            <Setter.Value>
                <ControlTemplate TargetType="gl:TreeItemBase">          
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto" MinWidth="19" />
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto" />
                            <RowDefinition />
                        </Grid.RowDefinitions>
                            <ToggleButton IsChecked="{TemplateBinding IsExpanded}" ClickMode="Press" Name="Expander">

    另外贴上我的测试代码

            IList<Item> data = new List<Item>();
    
            public MainWindow()
            {
                InitializeComponent();
    
    
                var group0 = new Item() { Id = Guid.NewGuid().ToString(), Header = "Root1" };
                group0.GetChidren += new Func<TreeItemBase, IEnumerable<TreeItemBase>>(group1_GetChidren);
    
                var group1 = new Item() { Id = Guid.NewGuid().ToString(), Header = "Root0" };
                group1.GetChidren += new Func<TreeItemBase, IEnumerable<TreeItemBase>>(group1_GetChidren);
    
                var item1 = new Item() { Id = Guid.NewGuid().ToString(), ParentId = group1.Id, Header = "Leaf1" };
                item1.GetChidren += new Func<TreeItemBase, IEnumerable<TreeItemBase>>(group1_GetChidren);
    
                var item2 = new Item() { Id = Guid.NewGuid().ToString(), ParentId = group1.Id, Header = "Leaf2" };
                item2.GetChidren += new Func<TreeItemBase, IEnumerable<TreeItemBase>>(group1_GetChidren);
    
                var item3 = new Item() { Id = Guid.NewGuid().ToString(), ParentId = group1.Id, Header = "Leaf3" };
                item3.GetChidren += new Func<TreeItemBase, IEnumerable<TreeItemBase>>(group1_GetChidren);
    
                var item4 = new Item() { Id = Guid.NewGuid().ToString(), ParentId = item3.Id, Header = "Leaf3:Leaf1" };
                item4.GetChidren += new Func<TreeItemBase, IEnumerable<TreeItemBase>>(group1_GetChidren);
    
                var item5 = new Item() { Id = Guid.NewGuid().ToString(), ParentId = item3.Id, Header = "Leaf3:Leaf2" };
                item5.GetChidren += new Func<TreeItemBase, IEnumerable<TreeItemBase>>(group1_GetChidren);
    
                var item6 = new Item() { Id = Guid.NewGuid().ToString(), ParentId = item3.Id, Header = "Leaf3:Leaf3" };
                item6.GetChidren += new Func<TreeItemBase, IEnumerable<TreeItemBase>>(group1_GetChidren);
    
                data.Add(group1);
                data.Add(item1);
                data.Add(item2);
                data.Add(item3);
                data.Add(item4);
                data.Add(item5);
                data.Add(item6);
    
    
                group0.Items.Add(group1);
                treeView1.ItemsSource = group0.Items;
    
    
            }
    
            IEnumerable<TreeItemBase> group1_GetChidren(TreeItemBase arg)
            {
                return data.Where(e => e.ParentId == (arg as Item).Id);
            }
    
    
        public class Item : TreeItemBase
        {
            public string Id { get; set; }
    
            public string ParentId { get; set; }
        }

    这里只是一种实现思路,大家如果有更好的实现方式或意见,欢迎大家指点。

  • 相关阅读:
    python中网络编程之线程
    python并发编程基础之守护进程、队列、锁
    python中并发编程基础1
    python中TCP粘包问题解决方案
    python中的异常处理常用方法
    python中面向对象元类的自定义用法
    python中类与对象之继承
    python中的re模块——正则表达式
    【2020090401】排名 rank over的用法
    【2020090301】mysql中 having 的用法
  • 原文地址:https://www.cnblogs.com/guanglin/p/3028511.html
Copyright © 2020-2023  润新知