wpf中,一个简单的自定义treeview
首先创建一个自定义控件,在里面定义好treeview的样式,将本来的三角形的图标变为加号的图标,并且添加节点之间的连线。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | <UserControl x:Class= "TreeViewEx.myTreeView" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x= "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc= "http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d= "http://schemas.microsoft.com/expression/blend/2008" xmlns:i= "clr-namespace:TreeViewEx" mc:Ignorable= "d" d:DesignHeight= "300" d:DesignWidth= "300" > <UserControl.Resources> <i:TreeViewLineConverter x:Key= "LineConverter" /> <!-- Toggle Button --> <Style x:Key= "ExpandCollapseToggleStyle" TargetType= "ToggleButton" > <Setter Property= "Focusable" Value= "False" /> <Setter Property= "Template" > <Setter.Value> <ControlTemplate TargetType= "ToggleButton" > <Grid Width= "20" Height= "18" SnapsToDevicePixels= "True" > <Rectangle Width= "12" Height= "12" Stroke= "#919191" SnapsToDevicePixels= "true" > <Rectangle.Fill> <LinearGradientBrush EndPoint= "0.5,2" StartPoint= "0.5,0" > <GradientStop Color= "White" Offset= "0" /> <GradientStop Color= "Silver" Offset= "0.5" /> <GradientStop Color= "LightGray" Offset= "1" /> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> <Rectangle x:Name= "ExpandPath" Width= "1" Height= "5" Stroke= "Black" SnapsToDevicePixels= "true" /> <Rectangle Width= "5" Height= "1" Stroke= "Black" SnapsToDevicePixels= "true" /> </Grid> <ControlTemplate.Triggers> <Trigger Property= "IsChecked" Value= "True" > <Setter Property= "Visibility" TargetName= "ExpandPath" Value= "Collapsed" /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> <!-- TreeViewItem --> <Style x:Key= "{x:Type TreeViewItem}" TargetType= "{x:Type TreeViewItem}" > <Setter Property= "Background" Value= "Transparent" /> <Setter Property= "Padding" Value= "1,0,0,0" /> <Setter Property= "Template" > <Setter.Value> <ControlTemplate TargetType= "{x:Type TreeViewItem}" > <Grid> <Grid.ColumnDefinitions> <ColumnDefinition MinWidth= "19" Width= "Auto" /> <ColumnDefinition Width= "Auto" /> <ColumnDefinition Width= "*" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height= "Auto" /> <RowDefinition/> </Grid.RowDefinitions> <!-- Connecting Lines --> <Rectangle x:Name= "HorLn" Margin= "9,1,0,0" Height= "1" Stroke= "#DCDCDC" SnapsToDevicePixels= "True" /> <Rectangle x:Name= "VerLn" Width= "1" Stroke= "#DCDCDC" Margin= "0,0,1,0" Grid.RowSpan= "2" SnapsToDevicePixels= "true" Fill= "White" /> <ToggleButton Margin= "-1,0,0,0" x:Name= "Expander" Style= "{StaticResource ExpandCollapseToggleStyle}" IsChecked= "{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}" ClickMode= "Press" /> <Border Name= "Bd" Grid.Column= "1" Background= "{TemplateBinding Background}" BorderBrush= "{TemplateBinding BorderBrush}" BorderThickness= "{TemplateBinding BorderThickness}" Padding= "{TemplateBinding Padding}" SnapsToDevicePixels= "True" > <ContentPresenter x:Name= "PART_Header" ContentSource= "Header" HorizontalAlignment= "{TemplateBinding HorizontalContentAlignment}" MinWidth= "20" /> </Border> <ItemsPresenter x:Name= "ItemsHost" Grid.Row= "1" Grid.Column= "1" Grid.ColumnSpan= "2" /> </Grid> <ControlTemplate.Triggers> <!-- This trigger changes the connecting lines if the item is the last in the list --> <DataTrigger Binding= "{Binding RelativeSource={RelativeSource Self}, Converter={StaticResource LineConverter}}" Value= "true" > <Setter TargetName= "VerLn" Property= "Height" Value= "9" /> <Setter TargetName= "VerLn" Property= "VerticalAlignment" Value= "Top" /> </DataTrigger> <Trigger Property= "IsExpanded" Value= "false" > <Setter TargetName= "ItemsHost" Property= "Visibility" Value= "Collapsed" /> </Trigger> <Trigger Property= "HasItems" Value= "false" > <Setter TargetName= "Expander" Property= "Visibility" Value= "Hidden" /> </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= "Green" /> <Setter Property= "Foreground" Value= "White" /> </MultiTrigger> <Trigger Property= "IsEnabled" Value= "false" > <Setter Property= "Foreground" Value= "{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </UserControl.Resources> <Grid> <TreeView BorderThickness= "0" > <TreeViewItem Header= "Program Files" > <TreeViewItem Header= "Header" /> </TreeViewItem> <TreeViewItem Header= "Program Data" IsExpanded= "True" > <TreeViewItem Header= "Microsoft" > <TreeViewItem Header= "Header" /> </TreeViewItem> <TreeViewItem Header= "Microsoft Help" /> </TreeViewItem> <TreeViewItem Header= "Uers" IsExpanded= "True" > <TreeViewItem Header= "Default" /> <TreeViewItem Header= "Public" IsExpanded= "True" > <TreeViewItem Header= "Libraries" /> <TreeViewItem Header= "Public Desktop" /> <TreeViewItem Header= "Public Documents" /> </TreeViewItem> <TreeViewItem Header= "TUYEN" > <TreeViewItem Header= "Header" /> </TreeViewItem> </TreeViewItem> <TreeViewItem Header= "Windows" /> </TreeView> </Grid> </UserControl> |
要注意上面的代码中有一句:xmlns:i="clr-namespace:TreeViewEx",这个TreeViewEx就是这个控件所在的命名空间,在这个控件的后台代码中添加一个类TreeViewLineConverter
class TreeViewLineConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { TreeViewItem item = (TreeViewItem)value; ItemsControl ic = ItemsControl.ItemsControlFromItemContainer(item); return ic.ItemContainerGenerator.IndexFromContainer(item) == ic.Items.Count - 1; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { return false; } }
这样控件就做完 了,然后在窗口中引用这个控件,同样的需要在窗体文件中添加xmlns:i="clr-namespace:TreeViewEx"。
<Grid>
<i:myTreeView />
</Grid>
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步