• Seaching TreeVIew WPF


    项目中有一个树形结构的资源,需要支持搜索功能,搜索出来的结果还是需要按照树形结构展示,下面是简单实现的demo。

    1.首先创建TreeViewItem的ViewModel,一般情况下,树形结构都包含DisplayName,Deepth,Parent,Children,Id, IndexCode,Visibility等属性,具体代码如下所示:

      1 using System;
      2 using System.Collections.Generic;
      3 using System.Collections.ObjectModel;
      4 using System.Linq;
      5 using System.Text;
      6 using System.Threading.Tasks;
      7 using System.Windows;
      8 
      9 namespace TreeViewDemo
     10 {
     11     public class TreeViewItemVM : NotifyPropertyChangedBase
     12     {
     13         public TreeViewItemVM ()
     14         {
     15             Visible = Visibility.Visible;
     16         }
     17 
     18         private TreeViewItemVM parent;
     19         public TreeViewItemVM Parent
     20         {
     21             get
     22             {
     23                 return this.parent;
     24             }
     25             set
     26             {
     27                 if (this.parent != value)
     28                 {
     29                     this.parent = value;
     30                     this.OnPropertyChanged(() => this.Parent);
     31                 }
     32             }
     33         }
     34 
     35         private ObservableCollection<TreeViewItemVM> children;
     36         public ObservableCollection<TreeViewItemVM> Children
     37         {
     38             get
     39             {
     40                 return this.children;
     41             }
     42             set
     43             {
     44                 if (this.children != value)
     45                 {
     46                     this.children = value;
     47                     this.OnPropertyChanged(() => this.Children);
     48                 }
     49             }
     50         }
     51 
     52         private string id;
     53         public string ID
     54         {
     55             get
     56             {
     57                 return this.id;
     58             }
     59             set
     60             {
     61                 if (this.id != value)
     62                 {
     63                     this.id = value;
     64                     this.OnPropertyChanged(() => this.ID);
     65                 }
     66             }
     67         }
     68 
     69         private string indexCode;
     70         public string IndexCode
     71         {
     72             get { return indexCode; }
     73             set
     74             {
     75                 if (indexCode != value)
     76                 {
     77                     indexCode = value;
     78                     this.OnPropertyChanged(() => IndexCode);
     79                 }
     80             }
     81         }
     82 
     83         private string displayName;
     84         public string DisplayName
     85         {
     86             get
     87             {
     88                 return this.displayName;
     89             }
     90             set
     91             {
     92                 if (this.displayName != value)
     93                 {
     94                     this.displayName = value;
     95                     this.OnPropertyChanged(() => this.DisplayName);
     96                 }
     97             }
     98         }
     99 
    100         private int deepth;
    101         public int Deepth
    102         {
    103             get
    104             {
    105                 return this.deepth;
    106             }
    107             set
    108             {
    109                 if (this.deepth != value)
    110                 {
    111                     this.deepth = value;
    112                     this.OnPropertyChanged(() => this.Deepth);
    113                 }
    114             }
    115         }
    116 
    117         private bool hasChildren;
    118         public bool HasChildren
    119         {
    120             get
    121             {
    122                 return this.hasChildren;
    123             }
    124             set
    125             {
    126                 if (this.hasChildren != value)
    127                 {
    128                     this.hasChildren = value;
    129                     this.OnPropertyChanged(() => this.HasChildren);
    130                 }
    131             }
    132         }
    133 
    134         private NodeType type;
    135         public NodeType Type
    136         {
    137             get { return type; }
    138             set
    139             {
    140                 if (type != value)
    141                 {
    142                     type = value;
    143                     OnPropertyChanged(() => this.Type);
    144                 }
    145             }
    146         }
    147 
    148         private Visibility visible;
    149         public Visibility Visible
    150         {
    151             get { return visible; }
    152             set
    153             {
    154                 if (visible != value)
    155                 {
    156                     visible = value;
    157                     OnPropertyChanged(() => this.Visible);
    158                 }
    159             }
    160         }
    161 
    162         public bool NameContains(string filter)
    163         {
    164             if (string.IsNullOrWhiteSpace(filter))
    165             {
    166                 return true;
    167             }
    168 
    169             return DisplayName.ToLowerInvariant().Contains(filter.ToLowerInvariant());
    170         }
    171     }
    172 }

    2.创建TreeViewViewModel,其中定义了用于过滤的属性Filter,以及过滤函数,并在构造函数中初始化一些测试数据,具体代码如下:

      1 using System;
      2 using System.Collections.Generic;
      3 using System.Collections.ObjectModel;
      4 using System.ComponentModel;
      5 using System.Linq;
      6 using System.Text;
      7 using System.Threading.Tasks;
      8 using System.Windows.Data;
      9 
     10 namespace TreeViewDemo
     11 {
     12     public class TreeViewViewModel : NotifyPropertyChangedBase
     13     {
     14         public static TreeViewViewModel Instance = new TreeViewViewModel();
     15 
     16         private TreeViewViewModel()
     17         {
     18             Filter = string.Empty;
     19 
     20             Root = new TreeViewItemVM()
     21             {
     22                 Deepth = 0,
     23                 DisplayName = "五号线",
     24                 HasChildren = true,
     25                 Type = NodeType.Unit,
     26                 ID = "0",
     27                 Children = new ObservableCollection<TreeViewItemVM>() { 
     28                     new TreeViewItemVM() { DisplayName = "站台", Deepth = 1, HasChildren = true, ID = "1", Type = NodeType.Region,
     29                         Children = new ObservableCollection<TreeViewItemVM>(){
     30                             new TreeViewItemVM() { DisplayName = "Camera 01", Deepth = 2, HasChildren = false, ID = "3",Type = NodeType.Camera },
     31                             new TreeViewItemVM() { DisplayName = "Camera 02", Deepth = 2, HasChildren = false, ID = "4",Type = NodeType.Camera },
     32                             new TreeViewItemVM() { DisplayName = "Camera 03", Deepth = 2, HasChildren = false, ID = "5",Type = NodeType.Camera },
     33                             new TreeViewItemVM() { DisplayName = "Camera 04", Deepth = 2, HasChildren = false, ID = "6",Type = NodeType.Camera },
     34                             new TreeViewItemVM() { DisplayName = "Camera 05", Deepth = 2, HasChildren = false, ID = "7", Type = NodeType.Camera},
     35                         }},
     36                     new TreeViewItemVM() { DisplayName = "进出口", Deepth = 1, HasChildren = true, ID = "10", Type = NodeType.Region,
     37                         Children = new ObservableCollection<TreeViewItemVM>(){
     38                             new TreeViewItemVM() { DisplayName = "Camera 11", Deepth = 2, HasChildren = false, ID = "13",Type = NodeType.Camera },
     39                             new TreeViewItemVM() { DisplayName = "Camera 12", Deepth = 2, HasChildren = false, ID = "14",Type = NodeType.Camera },
     40                             new TreeViewItemVM() { DisplayName = "Camera 13", Deepth = 2, HasChildren = false, ID = "15",Type = NodeType.Camera },
     41                             new TreeViewItemVM() { DisplayName = "Camera 14", Deepth = 2, HasChildren = false, ID = "16", Type = NodeType.Camera},
     42                             new TreeViewItemVM() { DisplayName = "Camera 15", Deepth = 2, HasChildren = false, ID = "17", Type = NodeType.Camera},
     43                         }},
     44                 }
     45             };
     46 
     47             InitTreeView();
     48         }
     49 
     50         private ObservableCollection<TreeViewItemVM> selectedCameras = new ObservableCollection<TreeViewItemVM>();
     51 
     52         private TreeViewItemVM root;
     53         public TreeViewItemVM Root
     54         {
     55             get
     56             {
     57                 return this.root;
     58             }
     59             set
     60             {
     61                 if (this.root != value)
     62                 {
     63                     this.root = value;
     64                     this.OnPropertyChanged(() => this.Root);
     65                 }
     66             }
     67         }
     68 
     69         /// <summary>
     70         /// 过滤字段
     71         /// </summary>
     72         private string filter;
     73         public string Filter
     74         {
     75             get
     76             {
     77                 return this.filter;
     78             }
     79             set
     80             {
     81                 if (this.filter != value)
     82                 {
     83 
     84                     this.filter = value;
     85                     this.OnPropertyChanged(() => this.Filter);
     86 
     87                     this.Refresh();
     88                 }
     89             }
     90         }
     91 
     92         /// <summary>
     93         /// View
     94         /// </summary>
     95         protected ICollectionView view;
     96         public ICollectionView View
     97         {
     98             get
     99             {
    100                 return this.view;
    101             }
    102             set
    103             {
    104                 if (this.view != value)
    105                 {
    106                     this.view = value;
    107                     this.OnPropertyChanged(() => this.View);
    108                 }
    109             }
    110         }
    111 
    112         /// <summary>
    113         /// 刷新View
    114         /// </summary>
    115         public void Refresh()
    116         {
    117             if (this.View != null)
    118             {
    119                 this.View.Refresh();
    120             }
    121         }
    122 
    123         private bool DoFilter(Object obj)
    124         {
    125             TreeViewItemVM item = obj as TreeViewItemVM;
    126             if (item == null)
    127             {
    128                 return true;
    129             }
    130 
    131             bool result = false;
    132             foreach (var node in item.Children)
    133             {
    134                 result = TreeItemDoFilter(node) || result;
    135             }
    136 
    137             return result || item.NameContains(this.Filter);
    138         }
    139 
    140         private bool TreeItemDoFilter(TreeViewItemVM vm)
    141         {
    142             if (vm == null)
    143             {
    144                 return true;
    145             }
    146 
    147             bool result = false;
    148             if (vm.Type == NodeType.Region || vm.Type == NodeType.Unit)
    149             {
    150                 foreach (var item in vm.Children)
    151                 {
    152                     result = TreeItemDoFilter(item) || result;
    153                 }
    154             }
    155 
    156             if (result || vm.NameContains(this.Filter))
    157             {
    158                 result = true;
    159                 vm.Visible = System.Windows.Visibility.Visible;
    160             }
    161             else
    162             {
    163                 vm.Visible = System.Windows.Visibility.Collapsed;
    164             }
    165 
    166             return result;
    167         }
    168 
    169         public void InitTreeView()
    170         {
    171             this.View = CollectionViewSource.GetDefaultView(this.Root.Children);
    172             this.View.Filter = this.DoFilter;
    173             this.Refresh();
    174         }
    175     }
    176 }

    3.在界面添加一个TreeView,并添加一个简单的Style,将ViewModel中必要数据进行绑定:

     1 <Window x:Class="TreeViewDemo.MainWindow"
     2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     4         Title="MainWindow" Height="450" Width="525">
     5     <Window.Resources>
     6         <Style x:Key="style" TargetType="{x:Type TreeViewItem}">
     7             <Setter Property="Template">
     8                 <Setter.Value>
     9                     <ControlTemplate TargetType="{x:Type TreeViewItem}">
    10                         <Grid Visibility="{Binding Visible}" Background="{Binding Background}">
    11                             <ContentPresenter ContentSource="Header"/>
    12                         </Grid>
    13                         
    14                         <ControlTemplate.Triggers>
    15                             <Trigger Property="IsSelected" Value="true">
    16                                 <Setter Property="Background" Value="Green"/>
    17                             </Trigger>
    18                         </ControlTemplate.Triggers>
    19                     </ControlTemplate>
    20                 </Setter.Value>
    21             </Setter>
    22         </Style>
    23     </Window.Resources>
    24     <Grid>
    25         <Grid.RowDefinitions>
    26             <RowDefinition Height="Auto"/>
    27             <RowDefinition Height="*"/>
    28         </Grid.RowDefinitions>
    29 
    30         <TextBox x:Name="searchTxt" Width="200" HorizontalAlignment="Center" Height="40"
    31                  Margin="20" Text="{Binding Filter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
    32 
    33         <TreeView
    34                   Grid.Row="1"
    35                   ItemsSource="{Binding View}">
    36             <TreeView.ItemTemplate>
    37                 <HierarchicalDataTemplate ItemContainerStyle ="{StaticResource style}"  ItemsSource="{Binding Children}">
    38                     <Grid Height="25" >
    39                         <TextBlock
    40                             x:Name="txt"
    41                             VerticalAlignment="Center"
    42                             Text="{Binding DisplayName}"    
    43                             TextTrimming="CharacterEllipsis"
    44                             ToolTip="{Binding DisplayName}" />
    45                     </Grid>
    46                 </HierarchicalDataTemplate>
    47             </TreeView.ItemTemplate>
    48         </TreeView>
    49     </Grid>
    50 </Window>

    4.在给界面绑定具体的数据

     1 using System.Windows;
     2 
     3 namespace TreeViewDemo
     4 {
     5     /// <summary>
     6     /// MainWindow.xaml 的交互逻辑
     7     /// </summary>
     8     public partial class MainWindow : Window
     9     {
    10         public MainWindow()
    11         {
    12             InitializeComponent();
    13             this.Loaded += MainWindow_Loaded;
    14         }
    15 
    16         void MainWindow_Loaded(object sender, RoutedEventArgs e)
    17         {
    18             this.DataContext = TreeViewViewModel.Instance;
    19         }
    20     }
    21 }

    5.运行结果:

     

  • 相关阅读:
    android 6.0 新特性
    接口_ _接口回调机制
    bug_ _
    volley_缓存介绍
    bug__android studio 出现布局文件不提示,且点击代码不能跟踪代码
    文章--笔记本蓝牙可以搜索到手机,但是怎么连接不了?
    Dialog_ _dialog系统样式讲解 及 透明背景
    动画_ _ Android应用开发之所有动画使用详解
    view坐标_ _ Android应用坐标系统全面详解
    html__脚本之家
  • 原文地址:https://www.cnblogs.com/Johar/p/10028962.html
Copyright © 2020-2023  润新知