TreeListView--拿来主义到底好不好

本文介绍了如何在WPF中实现TreeListView控件,并详细解释了其数据绑定过程及核心代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

写这篇博客的原因是:希望有在项目中遇到和我一样问题的人能够找到中文的解决方案,节省时间,仅此而已

 


此功能诸多代码来源于国外的网站和某些项目,地址为http://www.codeproject.com/Articles/30721/WPF-TreeListView-Control

 

我只是站在别人的楼顶,顶着风,尿了一把。

 

废话不多说,直接上效果图,一幕了然:


 

 


 

  接下来上的就是我这个代码的整体结构了。

    TreeListViewModel是CodeProject里面的人写的,为项目框架核心。

 


TreeListViewWpfApplication为TreeListView的主要实现,下面我主要介绍怎么实现

(TreeListViewModel里面代码能力有限,目前为止也没看出个什么东西) 

 

 

 


先给大家介绍Model下面的Student类的代码吧

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TreeListViewWpfApplication
{
     public  class Student
    {
         public Student( string types,  string name,  int age,  string love, List<Student> listStudent)
        {
            Types = types;
            Name = name;
            Age = age;
            Love = love;
            Childs = listStudent;
        }
         public Student() { }
         public  string Types {  getset; }
         public  string Name {  getset; }
         public  int Age {  getset; }
         public  string Love {  getset; }
         public List<Student> Childs {  getset; }
    }

 


下面要说的是绑定的数据的格式。

其实要实现TreeListView效果,绑定的数据类型必须实现接口ITreeModel。

接下来就需要我们来定义一个用来存储数据方式的类了(我这样说肯定有错误),这个类的名字为TreeListModel。

那接下贴上TreeListModel的代码。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TreeListViewModel.Tree;
using System.Collections;

namespace TreeListViewWpfApplication
{
     public  class SubTreeModel<T> : ITreeModel
    {
        List<TreeModel<T>> _trees =  new List<TreeModel<T>>();


         public SubTreeModel(List<TreeModel<T>> trees)
        {
            _trees = trees;
        }

         public IEnumerable GetChildren( object parent)
        {
             if (parent ==  null)
            {
                 foreach ( var item  in _trees)
                {
                     yield  return item;
                }
            }
             else
            {
                 var parentModel = parent  as TreeModel<T>;
                 if (parentModel !=  null)
                {
                     foreach ( var item  in parentModel.Childs)
                    {
                         yield  return item;
                    }
                }
            }
        }
         public  bool HasChildren( object parent)
        {
             var parentModel = parent  as TreeModel<T>;
             if (parentModel !=  null)
                 return parentModel.Childs.Count >  0;
             return  false;
        }
    }
     public  class TreeModel<T>
    {
        T item;
         public T Item
        {
             get {  return item; }
             set { item = value; }
        }

        List<TreeModel<T>> childs =  new List<TreeModel<T>>();

         public List<TreeModel<T>> Childs
        {
             get {  return childs; }
             set { childs = value; }
        }
    }

 

  如果对迭代器不是很懂的,下面的这个地址可以简单的了解一下迭代器的作用。

  

http://zhidao.baidu.com/question/74140086.html&__bd_tkn__=72b65727743787314d09ba79e9bf2eaa991792f58078338d51fed8133ea5c69d362ad36bb4bcda3b39bb3949f6bbe47087ac3af56e60b1f4e7eb60157f58fc369d67a1fe40491fc7006f377bdc40be083e75997f7922bd8fd23f300e705b4458c51203353ab2aba9ee09eabbc9db810ac23c23f549

 

  TreeModel<T>这个数据类型和Student一一对应。

  WPF前台绑定的数据类型为 SubTreeModel<T> 类型。


 

接下来我们看看WPF前台的代码 

 

 

< Window  x:Class ="TreeListViewWpfApplication.MainWindow"
        xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:tree
="clr-namespace:TreeListViewModel.Tree;assembly=TreeListViewModel"
        xmlns:local
="clr-namespace:TreeListViewWpfApplication"
        Title
="MainWindow"  Height ="350"  Width ="525" >
     < Window.Resources >
         < local:AgeConverter  x:Key ="AgeConverter" />
     </ Window.Resources >
     < Grid >
         < tree:TreeList  Name ="treeList" >
             < tree:TreeList.View >
                 < GridView >
                     < GridView.Columns >

                         < GridViewColumn  Width ="140"  Header ="Type" >
                             < GridViewColumn.CellTemplate >
                                 < DataTemplate >
                                     < StackPanel  Orientation ="Horizontal" >
                                         < tree:RowExpander />
                                         < TextBlock  Text =" {Binding Item.Types} " ></ TextBlock >
                                     </ StackPanel >
                                 </ DataTemplate >
                             </ GridViewColumn.CellTemplate >
                         </ GridViewColumn >
                         < GridViewColumn   Header ="Name"  Width ="100"  DisplayMemberBinding =" {Binding Item.Name} " />
                         < GridViewColumn  Header ="Age"  Width ="100"  DisplayMemberBinding =" {Binding Item.Age,Converter={StaticResource AgeConverter}} " />
                         < GridViewColumn  Header ="Love"  Width ="100"  DisplayMemberBinding =" {Binding Item.Love} " />
                     </ GridView.Columns >
                 </ GridView >
             </ tree:TreeList.View >
         </ tree:TreeList >
     </ Grid >
</ Window >

 

 

这里我就不把AgeConverter的代码帖出来了。

直接看MainWindow的后台代码吧。

MainWindow主要是给Student赋值并把数据填充到数据类型为 SubTreeModel<T>中。

即SubTreeModel<Student> ,对应SubTreeModel<T>中的List<TreeModel<T>>即List<TreeModel<Student>>

 

 TreeModel<Student>对应的是TreeModel<T>类,而TreeModel<T> 

里面包含 Item,和Childs属性,与Student类的Types字段和Childs字段刚好吻合。

下面是后台代码的实现 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace TreeListViewWpfApplication
{
     ///   <summary>
    
///  MainWindow.xaml 的交互逻辑
    
///   </summary>
     public  partial  class MainWindow : Window
    {
         public MainWindow()
        {
            InitializeComponent();
            Loaded +=  new RoutedEventHandler(MainWindow_Loaded);
        }
         void MainWindow_Loaded( object sender, RoutedEventArgs e)
        {
            Reload();
            treeList.Model = ListGasConfig;
        }

         private SubTreeModel<Student> _listGasConfig;

         public SubTreeModel<Student> ListGasConfig
        {
             get {  return _listGasConfig; }
             set
            {
                _listGasConfig = value;
            }
        }

         private  void Reload()
        {
             var configs =  new List<Student>(){
                 new Student ()
                { 
                    Types= " A ", Childs= new List<Student>()
                    { 
                         new Student(){ Name= " 测试A1 ", Age= 25, Love= " 赵某 ", Childs= null}, 
                         new Student(){ Name= " 测试A2 ", Age= 18, Love= " 小护士 ", Childs= null},
                    }
                },
                 new Student ()
                { 
                    Types= " B ", Childs= new List<Student>()
                    { 
                         new Student(){ Name= " 测试B1 ", Age= 24, Love= " 小琴 ", Childs= null}, 
                         new Student(){ Name= " 测试B2 ", Age= 22, Love= " 。。 ", Childs= null},
                    }
                },
                 new Student()
                {
                    Types= " The future ",Childs= new List<Student>()
                    {
                           new Student(){ Name= " The last one ", Age=- 1, Love= " 待定 ", Childs= null}
                    }
                }

            };
             var treeModels =  new List<TreeModel<Student>>();
             foreach (Student item  in configs)
            {
                 if (item.Childs !=  null)
                {
                    treeModels.Add(BuildTreeModels(item, item.Childs));
                }
            }
            ListGasConfig =  new SubTreeModel<Student>(treeModels);
        }

         private TreeModel<Student> BuildTreeModels(Student GasConfig, List<Student> liststudent)
        {
             var treeModel =  new TreeModel<Student>();

            treeModel.Item =  new Student() { Types = GasConfig.Types, Childs = liststudent };
             if (liststudent.Count >  0)
            {
                 foreach (Student item  in liststudent)
                {
                    treeModel.Childs.Add( new TreeModel<Student>() { Item = item });
                }
            }
             return treeModel;
        }
    }
}

 


   下面是我的DEMO,有码有真相,/Files/xuliangjie/TreeListView.rar

 


  再次申明,上述核心代码有很大一部分来自国外网站,我只是借鉴别人的核心,和我们项目中实际的运用,此篇文章不代表本人任何立场,我只是做个总结,分享一下,这个功能很实用。

 

 

 

 

 

转载于:https://www.cnblogs.com/xuliangjie/archive/2012/09/21/2696707.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值