如何实现具有层次结构的 TreeView <三> (WPF/TreeView/Style/Template)
2011-08-05 08:44
573 查看
数据模板 (DataTemplate) 和数据绑定 (Data Binding)
为了把数据和界面进行关联,我们要做 3 件事:
1、在 MainWindow.xaml 中添加一个 TreeView 控件
2、将数据绑定到 TreeView 控件上
在 WPF 中实现数据绑定的方法主要有2种: 在 XAML 中声明或在 Code 中指定。详细信息请参考 MSDN:
Windows Presentation Foundation 数据绑定 <一>
Windows Presentation Foundation 数据绑定 <二>
由于此处的 TreeView 顶层节点需要 ParentID 为 NULL 的数据,所以我采用了在 Code 中指定的方式。
关于 LINQ 请参考 MSDN:
LINQ 查询表达式 (C# 编程指南)
101 LINQ Samples
完成以上工作并运行程序,将看到类似下图中显示的界面:
从上面的图片可以看出,每一个 ListViewItem 都绑定了一个 Department 对象,由于我们尚未告诉 ListViewItem 如何显示 Department 对象的内容(即属性),所以系统默认分配了一个 TextBlock 控件,并将 Department.ToString() 的信息给呈现了出来。那 Department 的对象内容该如何显示呢?
3、为 TreeView 控件添加数据模板 (DataTemplate)
数据模板 (DataTemplate 类) 用于描述数据对象的可视化结构。
打个比方,当前工程中用到的数据对象是 Department,而每个 Department 都拥有4个属性: DepartmentID、ParentID、Name 和 Type。当我们将每个 Department 与 TreeViewItem 进行关联(即数据绑定)之后,我们应该告诉 TreeViewItem 如何呈现与其关联的 Department 对象,简单理解就是如何显示 Department 的那4个属性。而 DataTemplate 就是用来定义这个结构的东东。
通常,描述数据对象的可视化结构,直接使用 DataTemplate 就可以了。但是当前工程中的 Department 是可以包含“子部门”的数据项,而且其深度未知。所以,此处使用的是 HierarchicalDataTemplate 类,即允许包含“子数据项”的 DataTemplate.
例如:
a、使用一个
TextBlock 对象,仅用于呈现与该 ListViewItem 关联的 Department 对象的 Name 属性
b、稍微复杂一点的结构,呈现 Name(Type) 形式的2个属性。
通过上面2个简单的示例,我们应该对 DataTemplate 是如何描述数据对象的可视化结构有了一个直观的了解。
接下来,将介绍如何实现文本的纵向显示,这里有个概念需要先说明下:
一个字符串 (String) 可以被看作是一个字符数组 (Char[])
根据这一特性,我们可以将一个字符串作为数据源绑定到某个支持 ItemsSource 或 IsItemsHost 属性的控件上。例如: 将 Name 属性指定给 StackPanel、Grid、ListBox 或者 ItemsControl 等对象。
同时,基于 WPF 的数据转换规则,该字符串中的每个 Char 对象都将被自动转换为 String 对象输出到用户界面。
根据上述特征,修改一下 DataTemplate 就能实现文本的纵向显示了:
此时,数据绑定和数据模板定义已经完成。下一节将介绍:
1、如何布局 TreeView 控件,实现节点的横向排列 (从左到右,自上而下) 的视图。
2、为 TreeViewItem 设置控件模板 (ControlTemplate) 和触发器 (Trigger),令其在不同状态下呈现出不同的颜色、边框及背景等。
为了把数据和界面进行关联,我们要做 3 件事:
1、在 MainWindow.xaml 中添加一个 TreeView 控件
<TreeView x:Name="tv"> </TreeView>
2、将数据绑定到 TreeView 控件上
在 WPF 中实现数据绑定的方法主要有2种: 在 XAML 中声明或在 Code 中指定。详细信息请参考 MSDN:
Windows Presentation Foundation 数据绑定 <一>
Windows Presentation Foundation 数据绑定 <二>
由于此处的 TreeView 顶层节点需要 ParentID 为 NULL 的数据,所以我采用了在 Code 中指定的方式。
/// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); // 添加 MainWindow.Loaded 事件 this.Loaded += new RoutedEventHandler(MainWindow_Loaded); } private void MainWindow_Loaded(object sender, RoutedEventArgs e) { // 在代码中为 TreeView 控件设置 ItemsSource 属性 var dc = new CSDNBlogDataContext(); var items = dc.Departments.Where(item => item.ParentID == null); tv.ItemsSource = items.ToArray(); } }
关于 LINQ 请参考 MSDN:
LINQ 查询表达式 (C# 编程指南)
101 LINQ Samples
完成以上工作并运行程序,将看到类似下图中显示的界面:
从上面的图片可以看出,每一个 ListViewItem 都绑定了一个 Department 对象,由于我们尚未告诉 ListViewItem 如何显示 Department 对象的内容(即属性),所以系统默认分配了一个 TextBlock 控件,并将 Department.ToString() 的信息给呈现了出来。那 Department 的对象内容该如何显示呢?
3、为 TreeView 控件添加数据模板 (DataTemplate)
数据模板 (DataTemplate 类) 用于描述数据对象的可视化结构。
打个比方,当前工程中用到的数据对象是 Department,而每个 Department 都拥有4个属性: DepartmentID、ParentID、Name 和 Type。当我们将每个 Department 与 TreeViewItem 进行关联(即数据绑定)之后,我们应该告诉 TreeViewItem 如何呈现与其关联的 Department 对象,简单理解就是如何显示 Department 的那4个属性。而 DataTemplate 就是用来定义这个结构的东东。
通常,描述数据对象的可视化结构,直接使用 DataTemplate 就可以了。但是当前工程中的 Department 是可以包含“子部门”的数据项,而且其深度未知。所以,此处使用的是 HierarchicalDataTemplate 类,即允许包含“子数据项”的 DataTemplate.
例如:
a、使用一个
TextBlock 对象,仅用于呈现与该 ListViewItem 关联的 Department 对象的 Name 属性
<TreeView.ItemTemplate> <HierarchicalDataTemplate ItemsSource="{Binding Path=Children}"> <TextBlock Text="{Binding Path=Name}"/> </HierarchicalDataTemplate> </TreeView.ItemTemplate>
b、稍微复杂一点的结构,呈现 Name(Type) 形式的2个属性。
<TreeView.ItemTemplate> <HierarchicalDataTemplate ItemsSource="{Binding Path=Children}"> <!--<TextBlock Text="{Binding Path=Name}"/>--> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding Path=Name}"/> <TextBlock Text="("/> <TextBlock Text="{Binding Path=Type}"/> <TextBlock Text=")"/> </StackPanel> </HierarchicalDataTemplate> </TreeView.ItemTemplate>
通过上面2个简单的示例,我们应该对 DataTemplate 是如何描述数据对象的可视化结构有了一个直观的了解。
接下来,将介绍如何实现文本的纵向显示,这里有个概念需要先说明下:
一个字符串 (String) 可以被看作是一个字符数组 (Char[])
根据这一特性,我们可以将一个字符串作为数据源绑定到某个支持 ItemsSource 或 IsItemsHost 属性的控件上。例如: 将 Name 属性指定给 StackPanel、Grid、ListBox 或者 ItemsControl 等对象。
同时,基于 WPF 的数据转换规则,该字符串中的每个 Char 对象都将被自动转换为 String 对象输出到用户界面。
根据上述特征,修改一下 DataTemplate 就能实现文本的纵向显示了:
<TreeView.ItemTemplate> <HierarchicalDataTemplate ItemsSource="{Binding Path=Children}"> <!--<TextBlock Text="{Binding Path=Name}"/>--> <!--<StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding Path=Name}"/> <TextBlock Text="("/> <TextBlock Text="{Binding Path=Type}"/> <TextBlock Text=")"/> </StackPanel>--> <ItemsControl ItemsSource="{Binding Path=Name}"> <ItemsControl.Style> <Style TargetType="{x:Type ItemsControl}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ItemsControl}"> <Grid> <ItemsPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> </ItemsControl.Style> <ItemsControl.ItemTemplate> <DataTemplate> <TextBlock x:Name="block" RenderTransformOrigin="0.5,0.5" Text="{Binding}" TextAlignment="Center"/> <DataTemplate.Triggers> <DataTrigger Binding="{Binding}" Value="("> <Setter TargetName="block" Property="RenderTransform"> <Setter.Value> <RotateTransform Angle="90"/> </Setter.Value> </Setter> </DataTrigger> <DataTrigger Binding="{Binding}" Value=")"> <Setter TargetName="block" Property="RenderTransform"> <Setter.Value> <RotateTransform Angle="90"/> </Setter.Value> </Setter> </DataTrigger> <DataTrigger Binding="{Binding}" Value="-"> <Setter TargetName="block" Property="RenderTransform"> <Setter.Value> <RotateTransform Angle="90"/> </Setter.Value> </Setter> </DataTrigger> </DataTemplate.Triggers> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </HierarchicalDataTemplate> </TreeView.ItemTemplate>
此时,数据绑定和数据模板定义已经完成。下一节将介绍:
1、如何布局 TreeView 控件,实现节点的横向排列 (从左到右,自上而下) 的视图。
2、为 TreeViewItem 设置控件模板 (ControlTemplate) 和触发器 (Trigger),令其在不同状态下呈现出不同的颜色、边框及背景等。
相关文章推荐
- 如何实现具有层次结构的 TreeView <四> (WPF/TreeView/Style/Template)
- 如何实现具有层次结构的 TreeView <四> (WPF/TreeView/Style/Template)
- 如何实现具有层次结构的 TreeView <一> (WPF/TreeView/Style/Template)
- 如何实现具有层次结构的 TreeView <二> (WPF/TreeView/Style/Template)
- 如何实现具有层次结构的 TreeView 模版使用
- Wpf TextBox 控件如何绑定 Dictionary <int, string>
- 智能指针里弱引用应该如何实现?(WeakReference/WeakPtr<T>)
- 模拟实现通讯录<三> (文件流)
- Java 中如何对 Iterator<Text> values 实现两次遍历
- 数据结构学习笔记<三>数据结构算法2.2具体实现
- 探究 List<T> 集合的Where方法是如何实现的
- WPF中一个比较完整的树形结构<TreeView>和右键菜单<ContextMenu>
- WPF <ZoomableCanvas> 实现缩放移动
- quick-cocos2d-x的热更新机制实现<三>Updater(C++)
- JDBC系列-<驱动加载原理全面解析>-<JDBC层次结构和基本构成>-存储过程 CallableStatement(创建和使用)
- Android实战简易教程<三>(实现简单绘图组件)
- Android UI设计之<三>自定义EditText,实现带清除功能的输入框
- 如何实现IEnumerable<T>和IEnumerator接口,一个ASP.NET MVC日志模型的实现
- <vector> template实现
- Cocos2d入门 <三>如何移动精灵角色