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

 

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

 


此功能诸多代码来源于国外的网站和某些项目,地址为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

 


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

 

 

 

 

 

posted @ 2012-09-21 12:26  想要飞  阅读(2926)  评论(0编辑  收藏  举报