做项目的时候根据需求,WPF现有的控件不能完全满足我们的需求,

很多时候我们需要对现有的控件做一下加工。

最简单的我们可能会把Tree转换成List形式有的叫Grid形式就像下图一样

今天我先做一个完全用样式加工的例子,有时间我再把它做深加工写成一下通能形式

我们要先把treeView重写一下

public class TreeListView : TreeView
{
//这两个默认的是TreeViewItem
protected override DependencyObject GetContainerForItemOverride()//创建或标识用于显示指定项的元素。
{
return new TreeListViewItem();
} protected override bool IsItemItsOwnContainerOverride(object item)//确定指定项是否是(或可作为)其自己的 ItemContainer
{
//return item is TreeListViewItem;
bool _isTreeLVI = item is TreeListViewItem;
return _isTreeLVI;
}
} public class TreeListViewItem : TreeViewItem
{
/// <summary>
/// hierarchy
/// </summary>
public int Level
{
get
{
if (_level == -1)
{
TreeListViewItem parent =
ItemsControl.ItemsControlFromItemContainer(this) as TreeListViewItem;//返回拥有指定的容器元素中 ItemsControl 。
_level = (parent != null) ? parent.Level + 1 : 0;
}
return _level;
}
} protected override DependencyObject GetContainerForItemOverride()
{
return new TreeListViewItem();
} protected override bool IsItemItsOwnContainerOverride(object item)
{
//return item is TreeListViewItem;
bool _isITV = item is TreeListViewItem;
return _isITV;
} private int _level = -1;
}

上边是对TreeView的重写,因为TreeView是有层级关系的我们做的重写就把它的层级返回来

我们还要有一个列宽的转换

/// <summary>
///
///
/// </summary>
public class LevelToIndentConverter : IValueConverter
{
public object Convert(object o, Type type, object parameter, CultureInfo culture)
{
return new Thickness((int)o * c_IndentSize, 0, 0, 0);
} public object ConvertBack(object o, Type type, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
} private const double c_IndentSize = 25.0;
}

下边是样式和使用方法

我们是把TreeView的样式加上了GridViewColumnCollection实现 的这个TreeView和ListView一样有标头和列

前台页面

<Window x:Class="TreeViewListDemoT.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:l="clr-namespace:TreeViewListDemoT"
Title="MainWindow" Height="350" Width="525">
<Window.Resources> <Style x:Key="ExpandCollapseToggleStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="Focusable" Value="False"/>
<Setter Property="Width" Value="19"/>
<Setter Property="Height" Value="13"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Width="19" Height="13" Background="Transparent">
<Border Width="9" Height="9" BorderThickness="1" BorderBrush="#FF7898B5" CornerRadius="1" SnapsToDevicePixels="true">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<LinearGradientBrush.GradientStops>
<GradientStop Color="White" Offset=".2"/>
<GradientStop Color="#FFC0B7A6" Offset="1"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.Background>
<Path x:Name="ExpandPath" Margin="1,1,1,1" Fill="Black"
Data="M 0 2 L 0 3 L 2 3 L 2 5 L 3 5 L 3 3 L 5 3 L 5 2 L 3 2 L 3 0 L 2 0 L 2 2 Z"/>
</Border>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Data" TargetName="ExpandPath" Value="M 0 2 L 0 3 L 5 3 L 5 2 Z"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<l:LevelToIndentConverter x:Key="LevelToIndentConverter"/> <DataTemplate x:Key="CellTemplate_Name">
<DockPanel>
<ToggleButton x:Name="Expander" Style="{StaticResource ExpandCollapseToggleStyle}" Margin="{Binding Level,
Converter={StaticResource LevelToIndentConverter},RelativeSource={RelativeSource AncestorType={x:Type l:TreeListViewItem}}}"
IsChecked="{Binding Path=IsExpanded,RelativeSource={RelativeSource AncestorType={x:Type l:TreeListViewItem}}}" ClickMode="Press"/>
<TextBlock Text="{Binding Name}"/>
</DockPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=HasItems,RelativeSource={RelativeSource AncestorType={x:Type l:TreeListViewItem}}}" Value="False">
<Setter TargetName="Expander" Property="Visibility" Value="Hidden"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate> <GridViewColumnCollection x:Key="gvcc">
<GridViewColumn Header="Name" CellTemplate="{StaticResource CellTemplate_Name}" />
<GridViewColumn Header="Age" DisplayMemberBinding="{Binding Age}" Width="60" />
<GridViewColumn Header="Sex" DisplayMemberBinding="{Binding Sex}" Width="60"/>
</GridViewColumnCollection> <Style TargetType="{x:Type l:TreeListViewItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type l:TreeListViewItem}">
<StackPanel>
<Border Name="Bd"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}">
<GridViewRowPresenter x:Name="PART_Header"
Content="{TemplateBinding Header}"
Columns="{StaticResource gvcc}" />
</Border> <ItemsPresenter x:Name="ItemsHost" />
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="false">
<Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="HasHeader" Value="false"/>
<Condition Property="Width" Value="Auto"/>
</MultiTrigger.Conditions>
<Setter TargetName="PART_Header" Property="MinWidth" Value="75"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="HasHeader" Value="false"/>
<Condition Property="Height" Value="Auto"/>
</MultiTrigger.Conditions>
<Setter TargetName="PART_Header" Property="MinHeight" Value="19"/>
</MultiTrigger>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="Bd" Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter TargetName="Bd" Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style> <Style TargetType="{x:Type l:TreeListView}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type l:TreeListView}">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<DockPanel>
<GridViewHeaderRowPresenter Columns="{StaticResource gvcc}" DockPanel.Dock="Top"/>
<Border BorderThickness="2">
<ItemsPresenter/>
</Border>
</DockPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style> </Window.Resources>
<Grid>
<l:TreeListView x:Name="_list" ItemsSource="{Binding Children}" BorderThickness="2">
<l:TreeListView.ItemTemplate >
<HierarchicalDataTemplate ItemsSource="{Binding Children}" >
<Border BorderThickness="2" BorderBrush="Yellow" CornerRadius="0" Margin="1" x:Name="back" MinWidth="70"
DataContext="{Binding}" >
<StackPanel Orientation="Horizontal" Margin="2">
<TextBlock Text="{Binding Text}" Margin="2 0"/>
</StackPanel>
</Border>
</HierarchicalDataTemplate> </l:TreeListView.ItemTemplate> </l:TreeListView>
</Grid>
</Window>

后台代码

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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 TreeViewListDemoT
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
ObjForTest root = new ObjForTest();
ObjForTest depart = new ObjForTest("Department", null, "");
ObjForTest c1 = new ObjForTest( "li", 45, "M");
ObjForTest c2 = new ObjForTest( "xu", 30, "W");
ObjForTest c3 = new ObjForTest("zhang", 22, "M");
ObjForTest cc1 = new ObjForTest( "shen", 30, "M");
ObjForTest cc2 = new ObjForTest( "zhao", 18, "W");
ObjForTest cc3 = new ObjForTest( "wang", 32, "M");
ObjForTest ccc1 = new ObjForTest( "qian", 20, "W");
root.Children.Add(depart);
depart.Children.Add(c1);
depart.Children.Add(c2);
depart.Children.Add(c3);
c1.Children.Add(cc1);
c2.Children.Add(cc2);
c3.Children.Add(cc3);
cc1.Children.Add(ccc1);
this._list.ItemsSource = root.Children;
}
} public class ObjForTest
{
public ObjForTest() { }
public ObjForTest( string name, int? age, string sex)
{ this._sex = sex;
this._age = age;
this._name = name; }
private string _name;
private int? _age;
private string _sex; public string Sex
{
get { return this._sex; }
set { this._sex = value; }
}
public int? Age
{
get { return this._age; }
set { this._age = value; }
} public string Name
{
get { return _name; }
set
{
_name = value; }
} private ObservableCollection<ObjForTest> _children = new ObservableCollection<ObjForTest>();
public ObservableCollection<ObjForTest> Children
{
get { return _children; }
} }
}

最后给代码下载 TreeViewListDemoT.rar

WPF之TreeList的实现方法(一)的更多相关文章

  1. WPF之TreeList的实现方法1

    WPF之TreeList的实现方法(一) 做项目的时候根据需求,WPF现有的控件不能完全满足我们的需求, 很多时候我们需要对现有的控件做一下加工. 最简单的我们可能会把Tree转换成List形式有的叫 ...

  2. WPF实现MDI窗体的方法

    原文:WPF实现MDI窗体的方法 第一:新建一个类(Class) Win32Native.cs 代码如下: using System;  using System.Collections.Generi ...

  3. WPF文字描边的解决方法(二)——支持文字竖排和字符间距调整

    原文:WPF文字描边的解决方法(二)--支持文字竖排和字符间距调整 自前天格式化文本效果出来后,今天又添加文本竖排和调整字符间距的功能.另外,由于上次仓促,没来得及做有些功能的设计时支持,这次也调整好 ...

  4. WPF/C# 快捷键 自动生成方法

    原文:WPF/C# 快捷键 自动生成方法 这一篇文章会很短~ 在写依赖属性的会后   propdb 会自动生成依赖属性所有的内容 但是如果我写属性变化通知的时候   希望有一个快捷键能自动生成方法 怎 ...

  5. WPF支持GIF的各种方法

    2012.12.18更新:修复下载链接 已知WPF的Image元素只能显示GIF图片的第一帧,而MediaElement不能加载作为资源或内嵌的资源的GIF图片,所以网上有几种实现方法. 我抄袭网上提 ...

  6. WPF文字描边的解决方法

    原文:WPF文字描边的解决方法  由于项目原因,今天研究了一下午WPF的文字描边,网上这方面的资料奇少,搞了半天才发现强大的WPF原来不直接支持文字描边啊.最后求助于MSDN,找到了方案,和大家分 ...

  7. WPF中资源的引用方法

    一.引用同一个程序中的资源 1.使用相对Uri来引用资源,如下所示 img.Source=new BitmapImage(new Uri(@"d"\iamges\Backgroun ...

  8. WPF 得到子指定元素方法和得到指定子元素集合方法MvvM得到焦点

    public class UIHelper { /// <summary> /// 在Visual里找到想要的元素 /// childName可为空,不为空就按名字找 /// </s ...

  9. WPF中StackPanel的使用方法

    StackPanel 1.StackPanel:释义为是最简单的控制面板,它把其中的UI元素按横向或纵向堆积排列. 2.常用属性:width:获取或设置元素的宽度.Orientation:用于控制面板 ...

随机推荐

  1. Java Concurrency In Practice - Chapter 1 Introduction

    1.1. A (Very) Brief History of Concurrency motivating factors for multiple programs to execute simul ...

  2. 图解 SQL 各种连接查询之间的区别

    转载自:http://blog.csdn.net/xuanjiewu/article/details/50636465 对于SQL的Join,在学习起来可能是比较乱的.我们知道,SQL的Join语法有 ...

  3. nyoj 42 一笔画问题 欧拉路径

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=42 欧拉回路,欧拉路径水题~ 代码: #include "stdio.h&quo ...

  4. Linux系统之用户、群组和权限

    一.用户管理 创建用户时,系统为用户分配一个唯一的编号UID,同时为用户创建一个同名的组,并为组分配一个编号GID,并把该用户加入该组中. 系统规定: uid: 0       特权用户      u ...

  5. jquery发送异步请求

    var remark = $("#"+id+"remark").val(); var shopid = $("#"+id+"sho ...

  6. IPC之PIPE

    管道是一种只允许用在有亲属关系的进程间通信的方式,由函数pipe创建一个管道,read,write进行读写操作. #include <unistd.h> ]); 参数pipefd[2]数组 ...

  7. WEB安全--CSRF防御

    CSRF漏洞防御主要可以从三个层面进行,即服务端的防御.用户端的防御和安全设备的防御. 服务端的防御 目前服务器端防御CSRF攻击主要有5种策略(我知道的就这么多):验证HTTP Referer字段, ...

  8. Visualize real-time data streams with Gnuplot

    源文地址 (September 2008) For the last couple of years, I've been working on European Space Agency (ESA) ...

  9. shell script 学习笔记-----shell变量

    1.在赋值语句name=value中不能存在空格,例如:name = value这样的形式会被认为是三个变量,因为本质上来说,脚本的内容就是传给shell程序的变量,而变量之间是通过空格区分的.如果想 ...

  10. Adaboost 卡口车辆检测训练

    之前做了SVM的车脸检测,主要是针对车脸,接下来尝试利用Adaboost和Haar进行车脸的检测.我利用的主要是opencv中的cascade,其已经把Adaboost相关的算法做成了exe,直接调用 ...