这两天用到了Tree控件,发现在往树上绑定数据的时候不是特别方便,便写了一个辅助类。 在开始之前先说明一下如何使Tree控件支持有层次结构的数据源绑定,首先需要在xaml代码里为树增加HierarchicalDataTemplate模板,这样Tree就支持分层结构的数据源绑定了。

 

xaml代码如下:(注明:这里我还用到了一个Toolkit里的DragDrop控件,可以先忽略)

 

        <!--Tree-->
        <controlsToolkit:TreeViewDragDropTarget AllowDrop="true" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
            <controlsToolkit:TreeViewDragDropTarget.Resources>
                <common:HierarchicalDataTemplate x:Key="hierarchicalTemplate" ItemsSource="{Binding Children}">
                    <StackPanel Orientation="Horizontal">
                        <ContentPresenter Width="16" Height="16" Margin="0 0 4 0" Content="{Binding Icon}" />
                        <TextBlock Text="{Binding Name}"/>
                    </StackPanel>
                </common:HierarchicalDataTemplate>
            </controlsToolkit:TreeViewDragDropTarget.Resources>
            <controls:TreeView x:Name="tree1" ItemTemplate="{StaticResource hierarchicalTemplate}" AllowDrop="True"/>
        </controlsToolkit:TreeViewDragDropTarget>
 
 
辅助类的代码:
 
    /// <summary>
    /// Tree<T>
    /// </summary>
    public class Tree<T> where T: new()
    {
        /// <summary>
        /// 构造
        /// </summary>
        public Tree(string nodeName, string iconName = null)
        {
            this.Value = default(T);
            this.Children = new ObservableCollection<Tree<T>>();

            // 图标及名称
            this.Name = nodeName != null ? nodeName.Trim() : string.Empty;
            this.IconName = iconName != null ? iconName.Trim() : string.Empty;
        }

        /// <summary>
        /// 构造空节点
        /// </summary>
        public static Tree<T> Empty
        {
            get
            {
                return new Tree<T>(String.Empty);
            }
        }

        /// <summary>
        /// 构造实体
        /// </summary>
        public ObservableCollection<Tree<T>> Entity
        {
            get
            {
                ObservableCollection<Tree<T>> entity = new ObservableCollection<Tree<T>>();
                entity.Add(this);
                return entity;
            }
        }

        /// <summary>
        /// 子节点集合
        /// </summary>
        public ObservableCollection<Tree<T>> Children { get; set; }


        /// <summary>
        /// 节点值
        /// </summary>
        public T Value { get; set; }


        /// <summary>
        /// 图标名
        /// </summary>
        public string IconName { get; private set; }


        /// <summary>
        /// 名称
        /// </summary>
        public string Name { get; private set; }


        /// <summary>
        /// 图标
        /// </summary>
        public Image Icon
        {
            get
            {
               return ImageFactory.GetImage(this.IconName); // 加载图片的函数,这个自己根据需要实现吧。
            }
        }
    }
 
 
调用示例:
    创建一个SampleDataClass类,用做附加在树结点上的数据类型,替换成自己的具体类型就可以了,这里只是一个例子。
    public class SampleDataClass
    {
        public object Property1 { get; set; }
        public string Property2 { get; set; }
    }

 

    // 手动构造树结构
    Tree<SampleDataClass> root = new Tree<SampleDataClass>("Root", "Root.png");
        Tree<SampleDataClass> node1 = new Tree<SampleDataClass>("node1", "Folder.png");
            Tree<SampleDataClass> node2 = new Tree<SampleDataClass>("node2", "Folder.png");
            Tree<SampleDataClass> node3 = new Tree<SampleDataClass>("node3", "Folder.png");
        Tree<SampleDataClass> node4 = new Tree<SampleDataClass>("node4", "Folder.png");
        Tree<SampleDataClass> node5 = new Tree<SampleDataClass>("node5", "Folder.png");

    // 设定关系
    node1.Children.Add(node2);
    node1.Children.Add(node3);

    root.Children.Add(node1);
    root.Children.Add(node4);
    root.Children.Add(node5);

    // 绑定
    this.tree1.ItemsSource = root.Entity;

 

运行结果,如图:

image

 

已经可以用Tree<T>来管理你的数据结构了并且可以动态组织结构,同时可以使用Tree<T>.Value接口获取你在树结点上的附加数据。呃!上面那段示例的代码看上去很复杂?呵呵,其实那是因为我们是一行行自己组织的树结构,用程序实现那些树的结构和节点关系的话就优雅多了。再帖段实际应用时代码的样子:

 

    // 创建目录索引
    IDictionary<Guid, Tree<AH_Catalog>> treedict = new Dictionary<Guid, Tree<AH_Catalog>>();
    foreach (AH_Catalog catalog in catalogService.AH_Catalogs) {
        treedict[catalog.CatalogId] = new Tree<AH_Catalog>(catalog.Name, catalog.Icon) 
        { 
            Value = catalog 
        };
    }

    // 建立目录关系
    foreach (AH_CatalogInfo info in catalogService.AH_CatalogInfos) {
        treedict[info.Catalog].Children.Add(treedict[info.Children]);
    }

    // 加载根目录项
    foreach (Tree<AH_Catalog> node in treedict.Values.Where(w => w.Value.Depth == 0)) {
        treeRoot.Children.Add(node);
    }
    // 数据绑定
    this.tree1.ItemsSource = treeRoot.Entity;
 
运行结果:

image

 

第二帖END!

posted on 2009-12-19 09:41  老何BLOG  阅读(1406)  评论(8)    收藏  举报