上一篇 对Wpf/Silverlight Template 进行了总结,本篇继续上一篇,主要是介绍 HierarchicalDataTemplate 的使用方法。HierarchicalDataTemplate 继承于DataTemplate,被称之为"层级式数据模板",主要是应用层级比较明显数据集合,其典型的应用就是对TreeView控件进行数据绑定, 接下来就在Silverlight 5 下进行一下演示。最近有个卖凉茶的节目比较火,叫中国好声音,里面的导师和其歌手的分组就是个层级结构,我们暂且先用它来做个例子吧。

首先我们需要准备一下层级的数据集合,定义一个歌手类:

    /// <summary>
/// 歌手类
/// </summary>
public class Singer
{
/// <summary>
/// 歌手编号
/// </summary>
public int SingerId { get; set; } /// <summary>
/// 歌手名称
/// </summary>
public string SingerName { get; set; } /// <summary>
/// 歌手头像
/// </summary>
public string SingerHeader { get; set; }
}

然后定义一个 导师类,导师类中有个属性就是歌手的集合,代码如下:

    /// <summary>
/// 导师类
/// </summary>
public class Teacher
{
/// <summary>
/// 导师编号
/// </summary>
public int TeacherId { get; set; } /// <summary>
/// 导师名称
/// </summary>
public string TeacherName { get; set; } /// <summary>
/// 导师头像
/// </summary>
public string TeacherHeader { get; set; } /// <summary>
/// 学生列表
/// </summary>
public ObservableCollection<Singer> SingerList { get; set; }
}

接下来用代码组织一个导师与歌手的层级数据集合:

    /// <summary>
/// 好声音数据集合
/// </summary>
public class GoodVoice
{
public static ObservableCollection<Teacher> GoodVoiceData; static GoodVoice()
{
GoodVoiceData = new ObservableCollection<Teacher>();
GoodVoiceData.Add(new Teacher()
{
TeacherId = 1,
TeacherName = "刘欢",
TeacherHeader = @"Images/刘欢/刘欢.png",
SingerList = new ObservableCollection<Singer>()
{
new Singer(){ SingerId=1, SingerName="吉克隽逸",SingerHeader=@"Images/刘欢/吉克隽逸.png"},
new Singer(){ SingerId=2, SingerName="权振东",SingerHeader=@"Images/刘欢/权振东.png"},
new Singer(){ SingerId=3, SingerName="徐海星",SingerHeader=@"Images/刘欢/徐海星.png"},
new Singer(){ SingerId=4, SingerName="袁娅维",SingerHeader=@"Images/刘欢/袁娅维.png"},
}
}); GoodVoiceData.Add(new Teacher()
{
TeacherId = 2,
TeacherName = "那英",
TeacherHeader = @"Images/那英/那英.png",
SingerList = new ObservableCollection<Singer>()
{
new Singer(){ SingerId=5, SingerName="张炜",SingerHeader=@"Images/那英/张炜.png"},
new Singer(){ SingerId=6, SingerName="梁博",SingerHeader=@"Images/那英/梁博.png"},
new Singer(){ SingerId=7, SingerName="张赫宣",SingerHeader=@"Images/那英/张赫宣.png"},
new Singer(){ SingerId=8, SingerName="多亮",SingerHeader=@"Images/那英/多亮.png"},
}
}); GoodVoiceData.Add(new Teacher()
{
TeacherId = 3,
TeacherName = "杨坤",
TeacherHeader = @"Images/杨坤/杨坤.png",
SingerList = new ObservableCollection<Singer>()
{
new Singer(){ SingerId=9, SingerName="金志文",SingerHeader=@"Images/杨坤/金志文.png"},
new Singer(){ SingerId=10, SingerName="关喆",SingerHeader=@"Images/杨坤/关喆.png"},
new Singer(){ SingerId=11, SingerName="平安",SingerHeader=@"Images/杨坤/平安.png"},
new Singer(){ SingerId=12, SingerName="丁丁",SingerHeader=@"Images/杨坤/丁丁.png"},
}
}); GoodVoiceData.Add(new Teacher()
{
TeacherId = 4,
TeacherName = "庾澄庆",
TeacherHeader = @"Images/庾澄庆/庾澄庆.png",
SingerList = new ObservableCollection<Singer>()
{
new Singer(){ SingerId=9, SingerName="金池",SingerHeader=@"Images/庾澄庆/金池.png"},
new Singer(){ SingerId=10, SingerName="王韵壹",SingerHeader=@"Images/庾澄庆/王韵壹.png"},
new Singer(){ SingerId=11, SingerName="吴莫愁",SingerHeader=@"Images/庾澄庆/吴莫愁.png"},
new Singer(){ SingerId=12, SingerName="大山",SingerHeader=@"Images/庾澄庆/大山.png"},
}
});
}
}

有了数据集合,我们就可以在Xaml中编写我们的 HierarchicalDataTemplate 模版了,我们定义两个模版,一个TeacherTemplate 代表导师节点,一个SingerTemplate 代表歌手节点,并把TeacherTemplate中的ItemTemplate指定为SingerTemplate,具体代码如下:

<common:HierarchicalDataTemplate x:Key="SingerTemplate">
<StackPanel Orientation="Horizontal" Height="24">
<Image Source="{Binding SingerHeader}" Height="24" Width="24"/>
<TextBlock Text="{Binding SingerName}" Margin="2,0,0,0" VerticalAlignment="Center" FontSize="12" Foreground="Green" />
</StackPanel>
</common:HierarchicalDataTemplate> <common:HierarchicalDataTemplate x:Key="TeacherTemplate" ItemsSource="{Binding SingerList}" ItemTemplate="{StaticResource SingerTemplate}">
<StackPanel Orientation="Horizontal" Height="24">
<Image Source="{Binding TeacherHeader}" Height="24" Width="24" />
<TextBlock Text="{Binding TeacherName}" Margin="2,0,0,0" HorizontalAlignment="Center" FontSize="14" Foreground="Blue"/>
</StackPanel>
</common:HierarchicalDataTemplate>

在Silverlight下,需要在Xaml代码中添加如下命名空间:xmlns:common="clr-namespace:System.Windows;assembly=System.Windows.Controls"

在此之后,在主界面MainPage.xaml 中添加一个TreeView控件,并给该控件增加一个根节点,命名为 RootItem,并把该根节点的ItemTemplate指定为我们刚刚编写的层级模版中的 TeacherTemplate:

<sdk:TreeView x:Name="GoodVoiceTree" Width="200" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Stretch" VerticalContentAlignment="Stretch">
<sdk:TreeViewItem x:Name="RootItem" ItemTemplate="{StaticResource TeacherTemplate}" IsExpanded="True">
<sdk:TreeViewItem.HeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="images/中国好声音.png" Height="24" Width="24"/>
<TextBlock Text="中国好声音" Margin="2,0,0,0" VerticalAlignment="Center" FontSize="16" Foreground="Red" />
</StackPanel>
</DataTemplate>
</sdk:TreeViewItem.HeaderTemplate>
</sdk:TreeViewItem>
</sdk:TreeView>

接下来,我们为该树控件的根节点RootItem绑定我们的数据集合就可以展现我们的树形控件了:

this.RootItem.ItemsSource = GoodVoice.GoodVoiceData;

运行结果如下图:

其实在我们的实际开发项目中有些数据的层级结构是固定的,比如上面的例子,就固定了导师和歌手两个层级,固定的层级的话我们可以对每一层的样式方便的进行控制(直接在每层的模版中制作就可以)。但还有很多的时候,数据的层级是不固定的,我们也来进行一下简单的演示:

首先定义个TreeNode类,代表每层的数据模型:

    public class TreeNode
{
/// <summary>
/// 节点名称
/// </summary>
public string NodeName { get; set; } /// <summary>
/// 节点图片
/// </summary>
public string NodeImage { get; set; } /// <summary>
/// 是否展开
/// </summary>
public bool IsOpen { get; set; } /// <summary>
/// 子节点
/// </summary>
public ObservableCollection<TreeNode> ChildNode { get; set; }
}

同样用代码组织一个层级数据集合:

    public class TreeNodeData
{
public static ObservableCollection<TreeNode> TreeNodeList; static TreeNodeData()
{
TreeNodeList = new ObservableCollection<TreeNode>();
//根节点
TreeNode RootNode = new TreeNode()
{
NodeName = "根节点",
NodeImage = @"Images/Tree/Root.png",
IsOpen = true,
ChildNode = new ObservableCollection<TreeNode>()
}; //子节点A
TreeNode Node_A = new TreeNode()
{
NodeName = "子节点A",
NodeImage = @"Images/Tree/Node.png",
IsOpen = false,
ChildNode = new ObservableCollection<TreeNode>()
};
Node_A.ChildNode.Add(new TreeNode() { NodeName = "叶子节点A-1", NodeImage = @"Images/Tree/Leaf.png", IsOpen = false });
Node_A.ChildNode.Add(new TreeNode() { NodeName = "叶子节点A-2", NodeImage = @"Images/Tree/Leaf.png", IsOpen = false });
Node_A.ChildNode.Add(new TreeNode() { NodeName = "叶子节点A-3", NodeImage = @"Images/Tree/Leaf.png", IsOpen = false }); //子节点B
TreeNode Node_B = new TreeNode()
{
NodeName = "子节点B",
NodeImage = @"Images/Tree/Node.png",
IsOpen = true,
ChildNode = new ObservableCollection<TreeNode>()
};
Node_B.ChildNode.Add(new TreeNode() { NodeName = "叶子节点B-1", NodeImage = @"Images/Tree/Leaf.png", IsOpen = false });
Node_B.ChildNode.Add(new TreeNode() { NodeName = "叶子节点B-2", NodeImage = @"Images/Tree/Leaf.png", IsOpen = false }); //节点B 子节点B-3
TreeNode Node_B_3 = new TreeNode()
{
NodeName = "子节点B-3",
NodeImage = @"Images/Tree/SubNode.png",
IsOpen = false,
ChildNode = new ObservableCollection<TreeNode>()
};
Node_B_3.ChildNode.Add(new TreeNode() { NodeName = "叶子节点B-3-1", NodeImage = @"Images/Tree/Leaf.png", IsOpen = false });
Node_B_3.ChildNode.Add(new TreeNode() { NodeName = "叶子节点B-3-2", NodeImage = @"Images/Tree/Leaf.png", IsOpen = false }); Node_B.ChildNode.Add(Node_B_3);
RootNode.ChildNode.Add(Node_A);
RootNode.ChildNode.Add(Node_B); TreeNodeList.Add(RootNode); }
}

在Xaml中编写的层级模版:

<common:HierarchicalDataTemplate x:Key="TreeNodeTemplate" ItemsSource="{Binding ChildNode}" >
<StackPanel Orientation="Horizontal" Height="24">
<Image Source="{Binding NodeImage}" Height="24" Width="24" />
<TextBlock Text="{Binding NodeName}" Margin="2,0,0,0" HorizontalAlignment="Center" FontSize="12" Foreground="Blue"/>
</StackPanel>
</common:HierarchicalDataTemplate>

在这里我们需要注意一个问题:我们在TreeNode类的时候定义个一个布尔值属性 IsOpen, 就是利用这个属性来控制我们这棵树的节点的展开闭合状态的:True 代表该节点展开,False 代表该节点闭合。如果不这么做我们对 TreeView控件进行绑定后,树的初始状态都是闭合的,但是这种方法仅限于WPF 和 Silverlight 5 ,Silverlight4 及以下版本是不灵滴,不知道是不是Silverlight的一个Bug。

<sdk:TreeView x:Name="MyTree" Width="200" Grid.Row="1" Grid.Column="1"  ItemTemplate="{StaticResource TreeNodeTemplate}"
HorizontalAlignment="Stretch" VerticalContentAlignment="Stretch">
<sdk:TreeView.ItemContainerStyle>
<Style TargetType="sdk:TreeViewItem">
<Setter Property="IsExpanded" Value="{Binding IsOpen}"/>
</Style>
</sdk:TreeView.ItemContainerStyle>
</sdk:TreeView>

这里我们就利用了上一篇提到的TreeView的ItemContainerStyle属性,对TreeView中的所有TreeviewItem的IsExpander属性进行了绑定。

同样将我们的数据集合绑定到我们的这个TreeView控件上:

this.MyTree.ItemsSource = TreeNodeData.TreeNodeList;

由于我们在数据集合中对 根节点 和 子节点B 的IsOpen属性设置为了True,因此这两个节点是展开的,运行结果如下图:

至此,在Silverlight下利用HierarchicalDataTemplate 层级模版绑定TreeView控件的使用方式,演示完毕,至于如何获取TreeView 节点的数据,我们可以在TreeView控件中的SelectedItemChanged事件中进行获取,这里就不贴代码了,大家可以下载源码参看。

源码下载

作者:Rising Sun
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.

WPF/Silverlight HierarchicalDataTemplate 模版的使用(转)的更多相关文章

  1. WPF/Silverlight Template使用及总结(转)

    WPF/Silverlight 中的控件都有Style和Template两种属性.前者解释为样式,是用来改变控件原有属性的,比如 Button 控件的(Width,Height,Background ...

  2. XData -–无需开发、基于配置的数据库RESTful服务,可作为移动App和ExtJS、WPF/Silverlight、Ajax等应用的服务端

    XData -–无需开发.基于配置的数据库RESTful服务,可作为移动App和ExtJS.WPF/Silverlight.Ajax等应用的服务端   源起一个App项目,Web服务器就一台,已经装了 ...

  3. WPF/Silverlight Layout 系统概述——Arrange(转)

    Arrange过程概述 普通基类属性对Arrange过程的影响 我们知道Measure过程是在确定DesiredSize的大小,以便Arrange过程参考这个DesiredSize,确定给MyPane ...

  4. WPF/Silverlight Layout 系统概述——Measure(转)

    前言 在WPF/Silverlight当中,如果已经存在的Element无法满足你特殊的需求,你可能想自定义Element,那么就有可能会面临重写MeasureOverride和ArrangeOver ...

  5. Mvvm Light Toolkit for WPF/Silverlight系列之搭建mvvmlight开发框架

    Mvvm Light Toolkit for WPF/Silverlight系列之搭建mvvmlight开发框架   本章节,我将通过示例介绍如何搭建mvvmlight开发环境.示例中的我会针对wpf ...

  6. WPF/Silverlight深度解决方案:(一)解锁被Storyboard束缚的关联属性

    原文 WPF/Silverlight深度解决方案:(一)解锁被Storyboard束缚的关联属性 如果您在使用WPF/Silverlight进行相关动画开发中使用了Storyboard,并对关联属性进 ...

  7. WPF/Silverlight中图形的平移,缩放,旋转,倾斜变换演示

    原文:WPF/Silverlight中图形的平移,缩放,旋转,倾斜变换演示 为方便描述, 这里仅以正方形来做演示, 其他图形从略. 运行时效果图:XAML代码:// Transform.XAML< ...

  8. WPF/Silverlight中的RichTextBox总结

    WPF/Silverlight中的RichTextBox总结   在WPF或者是在Silverlight中有个非常强大的可以编辑的容器控件RichTextBox,有的时间会采取该控件来作为编辑控件.鉴 ...

  9. MvvmLight学习篇—— Mvvm Light Toolkit for wpf/silverlight系列(导航)

    系列一:看的迷迷糊糊的 一.Mvvm Light Toolkit for wpf/silverlight系列之准备工作 二.Mvvm Light Toolkit for wpf/silverlight ...

随机推荐

  1. C语言运算符优先级和口诀 (转)

    一共有十五个优先级: 1   ()  []  .  -> 2   !  ~   -(负号) ++  --   &(取变量地址)*   (type)(强制类型)    sizeof 3   ...

  2. [素材资源] Android开发性能优化简介(非常不错的)

    转自(http://www.starming.com/index.php?action=plugin&v=wave&tpl=union&ac=viewgrouppost& ...

  3. CSS3实现二十多种基本图形

    CSS3可以实现很多漂亮的图形,我收集了32种图形,在下面列出.直接用CSS3画出这些图形,要比贴图性能更好,体验更加,是一种非常好的网页美观方式. 这32种图形分别为圆形,椭圆形,三角形,倒三角形, ...

  4. sql大全

    推荐一. 简单查询   简单的Transact-SQL查询只包括选择列表.FROM子句和Where子句.它们分别说明所查询列.查询的表或视图.以及搜索条件等. 例如,下面的语句查询testtable表 ...

  5. ios 百度地图api 入门

    百度地图api 官方教程: http://developer.baidu.com/map/index.php?title=iossdk 这个非常好, 很适合新手 CLLocationCoordinat ...

  6. 使用 nginx + thin 的配置启动 rails server

    http://www.iwangzheng.com 在大师的指导下配置了新的服务器的nginx,通过top命令查看了服务器是8个cpu的,所以起了8个端口,把它们都映射到一个总的端口3600上,需要在 ...

  7. 对比WDCP面板与AMH面板的区别与选择

    转载: http://www.laozuo.org/2760.html | 老左博客 随着VPS主机的性价比提高(其实就是降价)我们很多站长会越来越多的选择使用VPS搭建网站或者运营一些项目,相比较而 ...

  8. samba服务搭建及管理

    关闭防火墙 # /etc/init.d/iptables stop # chkconfig --level iptables off 关闭SELINUX # vim /etc/sysconfig/se ...

  9. nc 常用命令

    nc(NetCat),在网络工具中有”瑞士军刀”的美誉,它短小精悍,功能强大,下面分享一些我平时经常用到的功能,更多的功能请google之. 1.基本参数想要连接到某处: nc [-options] ...

  10. Eclipse常用快捷键与代码模板

    Eclipse常用快捷键汇总 Eclipse的编辑功能非常强大,掌握了Eclipse快捷键功能,能够大大提高开发效率.Eclipse中有如下一些和编辑相关的快捷键.1. [ALT+/]此快捷键为用户编 ...