WPF之TreeList的实现方法(一)

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

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

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

WPF之TreeList的实现方法(一)

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

我们要先把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

 

你可能感兴趣的:(list)