• 重写TreeView,多层级节点下批量显示图片,图片支持缩略图和文件名列表切换,支持调用者动态匹配选中,支持外界拖入图片并添加到对应节点下


    1、先看下整体效果

    2、前端代码

      1 <UserControl x:Class="iPIS.UI.Base.Tree.ImageTreeControl"
      2              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      3              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      4              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      5              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      6              xmlns:local="clr-namespace:iPIS.UI.Base.Tree"
      7              mc:Ignorable="d" 
      8              d:DesignHeight="45" d:DesignWidth="80">
      9     <UserControl.Resources>
     10         <ResourceDictionary>
     11             <ResourceDictionary.MergedDictionaries>
     12                 <ResourceDictionary Source="/iPIS.UI.Themes.Black;component/Base/Tree/VideoTreeControlImages.xaml"/>
     13             </ResourceDictionary.MergedDictionaries>
     14             <Style TargetType="TextBlock" x:Key="treename">
     15                 <Setter Property="Foreground" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ImageTreeControlFontColor}"></Setter>
     16                 <Setter Property="FontSize" Value="14"></Setter>
     17             </Style>
     18         </ResourceDictionary>
     19     </UserControl.Resources>
     20     <TreeView x:Name="tree" 
     21               ItemsSource="{Binding DataList}"
     22               Background="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ImageTreeControlBackground}"
     23               >
     24         <TreeView.ItemTemplate>
     25             <HierarchicalDataTemplate ItemsSource="{Binding Children}">
     26                 <Grid Margin="-1 0 0 0"
     27                       Cursor="Hand"
     28                       Background="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ImageTreeControlBackground}"
     29                       >
     30                     <StackPanel x:Name="Classify" Orientation="Horizontal">
     31                         <Image Source="{Binding IconSource}" 
     32                                Width="25" 
     33                                Height="25" 
     34                                VerticalAlignment="Center"
     35                                Margin="0 0 10 0"
     36                                ></Image>
     37                         <TextBlock Text="{Binding Text}" 
     38                                    VerticalAlignment="Center"
     39                                    Style="{StaticResource treename}">
     40                         </TextBlock>
     41                         <TextBlock Style="{StaticResource treename}"
     42                                    VerticalAlignment="Center"
     43                             ></TextBlock>
     44                         <TextBlock Text="{Binding ImagesCount}"
     45                                    VerticalAlignment="Center"
     46                                    Style="{StaticResource treename}"
     47                                    ></TextBlock>
     48                         <TextBlock Style="{StaticResource treename}"
     49                                    VerticalAlignment="Center"
     50                             ></TextBlock>
     51                     </StackPanel>
     52                     <!--缩略图视图-->
     53                     <ListBox x:Name="Image_slt" 
     54                              ItemsSource="{Binding Images}" 
     55                              Visibility="Collapsed"
     56                              Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ThumbnailWidth}"
     57                              Background="Transparent"
     58                              Margin="-35 0 0 0"
     59                              >
     60                         <ListBox.Template>
     61                             <ControlTemplate TargetType="{x:Type ListBox}">
     62                                 <ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
     63                                     <WrapPanel Orientation="Horizontal" IsItemsHost="True"></WrapPanel>
     64                                 </ScrollViewer>
     65                             </ControlTemplate>
     66                         </ListBox.Template>
     67                         <ListBox.ItemTemplate>
     68                             <DataTemplate>
     69                                 <Border x:Name="border" 
     70                                         BorderBrush="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ImageTreeControlImageBoderColor}" 
     71                                         Background="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ImageTreeControlImageBoderColor}"
     72                                         BorderThickness="3"                            
     73                                         Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ImageTreeControlImageWidth}" 
     74                                         Height="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ImageTreeControlImageHeight}"
     75                                         >
     76                                     <Grid>
     77                                         <Image Source="{Binding ImageSource}"
     78                                                Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ImageTreeControlImageWidth}" 
     79                                                Height="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ImageTreeControlImageHeight}" 
     80                                                ></Image>
     81                                         <Image x:Name="icon" Visibility="Collapsed" Width="13" Height="14" Margin="-72 -50 0 0"></Image>
     82                                     </Grid>
     83                                 </Border>
     84                                 <DataTemplate.Triggers>
     85                                     <DataTrigger Binding="{Binding Type}" Value="1">
     86                                         <Setter TargetName="icon" Property="Visibility" Value="Visible"></Setter>
     87                                         <Setter TargetName="icon" Property="Source" Value="{StaticResource icon_kou}"></Setter>
     88                                     </DataTrigger>
     89                                     <DataTrigger Binding="{Binding Type}" Value="2">
     90                                         <Setter TargetName="icon" Property="Visibility" Value="Visible"></Setter>
     91                                         <Setter TargetName="icon" Property="Source" Value="{StaticResource icon_jiandao}"></Setter>
     92                                     </DataTrigger>
     93                                     <DataTrigger Binding="{Binding IsSelected}" Value="true">
     94                                         <Setter TargetName="border" 
     95                                                 Property="BorderBrush" 
     96                                                 Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ImageTreeControlImageSelectedBoderColor}"
     97                                                 ></Setter>
     98                                     </DataTrigger>
     99                                     <Trigger Property="IsMouseOver" Value="true">
    100                                         <Setter TargetName="border" 
    101                                                 Property="BorderBrush" 
    102                                                 Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ImageTreeControlImageMouseOverBoderColor}"
    103                                                 ></Setter>
    104                                     </Trigger>
    105                                 </DataTemplate.Triggers>
    106                             </DataTemplate>
    107                         </ListBox.ItemTemplate>
    108                         <ListBox.ItemContainerStyle>
    109                             <Style TargetType="ListBoxItem">
    110                                 <Setter Property="Padding" Value="0"></Setter>
    111                                 <Setter Property="BorderThickness" Value="0"></Setter>
    112                                 <Setter Property="Margin" Value="1"></Setter>
    113                             </Style>
    114                         </ListBox.ItemContainerStyle>
    115                     </ListBox>
    116                     <!--文件名视图-->
    117                     <ListBox x:Name="Image_file" 
    118                              ItemsSource="{Binding Images}"
    119                              BorderThickness="0"
    120                              Background="Transparent"
    121                              Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ListWidth}"
    122                              Margin="-35 0 0 0"
    123                              >
    124                         <ListBox.ItemTemplate>
    125                             <DataTemplate>
    126                                 <TextBlock x:Name="text" 
    127                                            Text="{Binding Text}"
    128                                            Foreground="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ImageTreeControlImageImgNameColor}"
    129                                            ></TextBlock>
    130                                 <DataTemplate.Triggers>
    131                                     <DataTrigger Binding="{Binding IsSelected}" Value="true">
    132                                         <Setter TargetName="text" 
    133                                                 Property="Foreground" 
    134                                                 Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ImageTreeControlImageSelectedImgNameColor}"
    135                                                 ></Setter>
    136                                     </DataTrigger>
    137                                 </DataTemplate.Triggers>
    138                             </DataTemplate>
    139                         </ListBox.ItemTemplate>
    140                     </ListBox>
    141                 </Grid>
    142                 <HierarchicalDataTemplate.Triggers>
    143                     <DataTrigger Binding="{Binding Type}" Value="0">
    144                         <Setter TargetName="Classify" Property="Visibility" Value="Visible"></Setter>
    145                         <Setter TargetName="Image_slt" Property="Visibility" Value="Collapsed"></Setter>
    146                         <Setter TargetName="Image_file" Property="Visibility" Value="Collapsed"></Setter>
    147                     </DataTrigger>
    148                     <DataTrigger Binding="{Binding Type}" Value="1">
    149                         <Setter TargetName="Classify" Property="Visibility" Value="Collapsed"></Setter>
    150                     </DataTrigger>
    151                     <MultiDataTrigger>
    152                         <MultiDataTrigger.Conditions>
    153                             <Condition Binding="{Binding Type}" Value="1"></Condition>
    154                             <Condition Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ImageTreeControlViewState}" Value="0"></Condition>
    155                         </MultiDataTrigger.Conditions>
    156                         <Setter TargetName="Image_slt" Property="Visibility" Value="Collapsed"></Setter>
    157                         <Setter TargetName="Image_file" Property="Visibility" Value="Visible"></Setter>
    158                     </MultiDataTrigger>
    159                     <MultiDataTrigger>
    160                         <MultiDataTrigger.Conditions>
    161                             <Condition Binding="{Binding Type}" Value="1"></Condition>
    162                             <Condition Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ImageTreeControlViewState}" Value="1"></Condition>
    163                         </MultiDataTrigger.Conditions>
    164                         <Setter TargetName="Image_slt" Property="Visibility" Value="Visible"></Setter>
    165                         <Setter TargetName="Image_file" Property="Visibility" Value="Collapsed"></Setter>
    166                     </MultiDataTrigger>
    167                 </HierarchicalDataTemplate.Triggers>
    168 
    169             </HierarchicalDataTemplate>
    170         </TreeView.ItemTemplate>
    171     </TreeView>
    172 </UserControl>
    View Code

    3、控件后台代码 

      1 using iPIS.UI.Base.Model;
      2 using iPIS.UI.Base.ViewModel;
      3 using iPIS.Utility;
      4 using System;
      5 using System.Collections.Generic;
      6 using System.Linq;
      7 using System.Text;
      8 using System.Threading.Tasks;
      9 using System.Windows;
     10 using System.Windows.Controls;
     11 using System.Windows.Data;
     12 using System.Windows.Documents;
     13 using System.Windows.Input;
     14 using System.Windows.Media;
     15 using System.Windows.Media.Imaging;
     16 using System.Windows.Navigation;
     17 using System.Windows.Shapes;
     18 
     19 namespace iPIS.UI.Base.Tree
     20 {
     21     /// <summary>
     22     /// ImageTreeControl.xaml 的交互逻辑
     23     /// </summary>
     24     public partial class ImageTreeControl : UserControl
     25     {
     26         public ImageTreeControl()
     27         {
     28             InitializeComponent();
     29             var vm = new ImageTreeControlViewModel(this);
     30             this.DataContext = vm;
     31             this.PreviewDragOver += ImageTreeControl_PreviewDragOver;
     32             this.PreviewDrop += ImageTreeControl_PreviewDrop;
     33             this.SizeChanged += ImageTreeControl_SizeChanged;
     34 
     35             //默认样式
     36             ImageTreeControlViewState = 1;
     37             ImageTreeControlImageWidth = 85;
     38             ImageTreeControlImageHeight = 65;
     39             ImageTreeControlBackground = "#36353a";
     40             ImageTreeControlFontColor = "#89888d";
     41             ImageTreeControlImageBoderColor = "#000000";
     42             ImageTreeControlImageSelectedBoderColor = "#019e97";
     43             ImageTreeControlImageMouseOverBoderColor = ImageTreeControlImageSelectedBoderColor;
     44             ImageTreeControlImageImgNameColor = ImageTreeControlFontColor;
     45             ImageTreeControlImageSelectedImgNameColor = ImageTreeControlImageSelectedBoderColor;
     46 
     47             //测试数据
     48             test();
     49         }
     50 
     51         /// <summary>
     52         /// 大小发送变化时
     53         /// </summary>
     54         /// <param name="sender"></param>
     55         /// <param name="e"></param>
     56         private void ImageTreeControl_SizeChanged(object sender, SizeChangedEventArgs e)
     57         {
     58             ThumbnailWidth = (int)this.Width - 10;
     59             ListWidth = (int)this.Width - 25;
     60         }
     61 
     62         private void test()
     63         {
     64             //模拟数据
     65             var list = new Client.WebApiWrap.PVL.FileCategoryApiWrap().GetFileCategoryList("ac165316-6630-40ba-84bb-fba75475d713", 2, 2, -1, 1);
     66             var datas = new List<ImageTreeControlItemModel>();
     67             for (int j = 0; j < list.Count; j++)
     68             {
     69                 var item = list[j];
     70                 ImageTreeControlItemModel root = new ImageTreeControlItemModel();
     71                 root.Text = item.CategoryName;
     72                 root.Value = item;
     73                 root.Images = new List<ImageTreeControlImageModel>();
     74                 for (int i = 0; i < 10; i++)
     75                 {
     76                     root.Images.Add(new ImageTreeControlImageModel()
     77                     {
     78                         ImageSource = new BitmapImage(new Uri(PublicMethod.GetSet("Web") + "/images/defaut.png")),
     79                         Text = "我是名称"
     80                     });
     81                 }
     82                 if (j == list.Count - 1)
     83                 {
     84                     ImageTreeControlItemModel m = new ImageTreeControlItemModel();
     85                     m.Text = "我是第二级";
     86                     m.Images = new List<ImageTreeControlImageModel>();
     87                     for (int i = 0; i < 10; i++)
     88                     {
     89                         m.Images.Add(new ImageTreeControlImageModel()
     90                         {
     91                             ImageSource = new BitmapImage(new Uri(PublicMethod.GetSet("Web") + "/images/defaut.png")),
     92                             Text = "我是第二级的图片"
     93                         });
     94                     }
     95                     root.Children = new List<ImageTreeControlItemModel>() { m };
     96                 }
     97                 datas.Add(root);
     98             }
     99             vm.SetDataList(datas);
    100         }
    101 
    102         /// <summary>
    103         /// 上下文
    104         /// </summary>
    105         public ImageTreeControlViewModel vm
    106         {
    107             get
    108             {
    109                 return this.DataContext as ImageTreeControlViewModel;
    110             }
    111         }
    112 
    113         /// <summary>
    114         /// 背景色
    115         /// </summary>
    116         public string ImageTreeControlBackground
    117         {
    118             get { return (string)GetValue(ImageTreeControlBackgroundProperty); }
    119             set { SetValue(ImageTreeControlBackgroundProperty, value); }
    120         }
    121 
    122         /// <summary>
    123         /// 视图状态,默认文件名形式
    124         /// 0:文件名称;1:缩略图
    125         /// </summary>
    126         public int ImageTreeControlViewState
    127         {
    128             get { return (int)GetValue(ImageTreeControlViewStateProperty); }
    129             set { SetValue(ImageTreeControlViewStateProperty, value); }
    130         }
    131 
    132         /// <summary>
    133         /// 缩略图模式,显示的图片宽度
    134         /// </summary>
    135         public int ImageTreeControlImageWidth
    136         {
    137             get { return (int)GetValue(ImageTreeControlImageWidthProperty); }
    138             set { SetValue(ImageTreeControlImageWidthProperty, value); }
    139         }
    140 
    141         /// <summary>
    142         /// 缩略图模式,显示的图片高度
    143         /// </summary>
    144         public int ImageTreeControlImageHeight
    145         {
    146             get { return (int)GetValue(ImageTreeControlImageHeightProperty); }
    147             set { SetValue(ImageTreeControlImageHeightProperty, value); }
    148         }
    149 
    150         /// <summary>
    151         /// 树状控件的节点名称字体样式
    152         /// </summary>
    153         public string ImageTreeControlFontColor
    154         {
    155             get { return (string)GetValue(ImageTreeControlFontColorProperty); }
    156             set { SetValue(ImageTreeControlFontColorProperty, value); }
    157         }
    158 
    159         /// <summary>
    160         /// 默认状态下,图片的边框样式
    161         /// </summary>
    162         public string ImageTreeControlImageBoderColor
    163         {
    164             get { return (string)GetValue(ImageTreeControlImageBoderColorProperty); }
    165             set { SetValue(ImageTreeControlImageBoderColorProperty, value); }
    166         }
    167 
    168         /// <summary>
    169         /// 缩略图模式的容器宽度
    170         /// </summary>
    171         public int ThumbnailWidth
    172         {
    173             get { return (int)GetValue(ThumbnailWidthProperty); }
    174             private set { SetValue(ThumbnailWidthProperty, value); }
    175         }
    176 
    177         /// <summary>
    178         /// 文件名称视图的容器宽度
    179         /// </summary>
    180         public int ListWidth
    181         {
    182             get { return (int)GetValue(ListWidthProperty); }
    183             private set { SetValue(ListWidthProperty, value); }
    184         }
    185 
    186         /// <summary>
    187         /// 选中状态下,图片边框的样式
    188         /// </summary>
    189         public string ImageTreeControlImageSelectedBoderColor
    190         {
    191             get { return (string)GetValue(ImageTreeControlImageSelectedBoderColorProperty); }
    192             set { SetValue(ImageTreeControlImageSelectedBoderColorProperty, value); }
    193         }
    194 
    195         /// <summary>
    196         /// 鼠标悬浮图片上,图片边框的样式
    197         /// </summary>
    198         public string ImageTreeControlImageMouseOverBoderColor
    199         {
    200             get { return (string)GetValue(ImageTreeControlImageMouseOverBoderColorProperty); }
    201             set { SetValue(ImageTreeControlImageMouseOverBoderColorProperty, value); }
    202         }
    203 
    204         /// <summary>
    205         /// 默认状态,列表模式,图片名称的样式
    206         /// </summary>
    207         public string ImageTreeControlImageImgNameColor
    208         {
    209             get { return (string)GetValue(ImageTreeControlImageImgNameColorProperty); }
    210             set { SetValue(ImageTreeControlImageImgNameColorProperty, value); }
    211         }
    212 
    213         /// <summary>
    214         /// 选中状态下,列表模式,图片名称的样式
    215         /// </summary>
    216         public string ImageTreeControlImageSelectedImgNameColor
    217         {
    218             get { return (string)GetValue(ImageTreeControlImageSelectedImgNameColorProperty); }
    219             set { SetValue(ImageTreeControlImageSelectedImgNameColorProperty, value); }
    220         }
    221 
    222         #region 附加属性
    223 
    224         public static readonly DependencyProperty ListWidthProperty =
    225             DependencyProperty.Register("ListWidth", typeof(int), typeof(ImageTreeControl), new PropertyMetadata(0));
    226 
    227         public static readonly DependencyProperty ThumbnailWidthProperty =
    228             DependencyProperty.Register("ThumbnailWidth", typeof(int), typeof(ImageTreeControl), new PropertyMetadata(0));
    229 
    230         public static readonly DependencyProperty ImageTreeControlImageMouseOverBoderColorProperty =
    231             DependencyProperty.Register("ImageTreeControlImageMouseOverBoderColor", typeof(string), typeof(ImageTreeControl), new PropertyMetadata(""));
    232 
    233         public static readonly DependencyProperty ImageTreeControlImageImgNameColorProperty =
    234             DependencyProperty.Register("ImageTreeControlImageImgNameColor", typeof(string), typeof(ImageTreeControl), new PropertyMetadata(""));
    235 
    236         public static readonly DependencyProperty ImageTreeControlImageSelectedImgNameColorProperty =
    237             DependencyProperty.Register("ImageTreeControlImageSelectedImgNameColor", typeof(string), typeof(ImageTreeControl), new PropertyMetadata(""));
    238 
    239         public static readonly DependencyProperty ImageTreeControlImageSelectedBoderColorProperty =
    240             DependencyProperty.Register("ImageTreeControlImageSelectedBoderColor", typeof(string), typeof(ImageTreeControl), new PropertyMetadata(""));
    241 
    242         public static readonly DependencyProperty ImageTreeControlImageBoderColorProperty =
    243             DependencyProperty.Register("ImageTreeControlImageBoderColor", typeof(string), typeof(ImageTreeControl), new PropertyMetadata(""));
    244 
    245         public static readonly DependencyProperty ImageTreeControlFontColorProperty =
    246             DependencyProperty.Register("ImageTreeControlFontColor", typeof(string), typeof(ImageTreeControl), new PropertyMetadata(""));
    247 
    248         public static readonly DependencyProperty ImageTreeControlImageHeightProperty =
    249             DependencyProperty.Register("ImageTreeControlImageHeight", typeof(int), typeof(ImageTreeControl), new PropertyMetadata(0));
    250 
    251         public static readonly DependencyProperty ImageTreeControlImageWidthProperty =
    252             DependencyProperty.Register("ImageTreeControlImageWidth", typeof(int), typeof(ImageTreeControl), new PropertyMetadata(0));
    253 
    254         public static readonly DependencyProperty ImageTreeControlViewStateProperty =
    255             DependencyProperty.Register("ImageTreeControlViewState", typeof(int), typeof(ImageTreeControl), new PropertyMetadata(0));
    256 
    257         public static readonly DependencyProperty ImageTreeControlBackgroundProperty =
    258             DependencyProperty.Register("ImageTreeControlBackground", typeof(string), typeof(ImageTreeControl), new PropertyMetadata(""));
    259 
    260         #endregion
    261 
    262         /// <summary>
    263         /// 拖进来了
    264         /// </summary>
    265         /// <param name="sender"></param>
    266         /// <param name="e"></param>
    267         private void ImageTreeControl_PreviewDrop(object sender, DragEventArgs e)
    268         {
    269             var data = e.Data.GetData(typeof(ImageTreeControlImageModel));
    270             if (data == null) return;
    271             Point point = e.GetPosition(tree);
    272             HitTestResult result = VisualTreeHelper.HitTest(tree, point);
    273             if (result == null)
    274                 return;
    275             TreeViewItem treeitem = Utils.FindVisualParent<TreeViewItem>(result.VisualHit);
    276             if (treeitem == null)
    277                 return;
    278             var vm_item = treeitem.DataContext as ImageTreeControlItemModelPackage;
    279             if (vm_item == null)
    280                 return;
    281             if (vm_item.Type == ImageTreeControlItemType.Classify)
    282             {
    283                 var imags = vm_item.Children.Where(c => c.Type == ImageTreeControlItemType.Images).ToList();
    284                 if (imags.Count == 0)
    285                 {
    286                     ImageTreeControlItemModelPackage item = new ImageTreeControlItemModelPackage(vm_item);
    287                     item.Type = ImageTreeControlItemType.Images;
    288                     vm_item.Children.Add(item);
    289                     imags = vm_item.Children.Where(c => c.Type == ImageTreeControlItemType.Images).ToList();
    290                 }
    291                 else if (imags.Count > 1)
    292                 {
    293                     MessageBox.Show("抱歉,当前节点下面有多个子集,无法确定你想存放的位置,请拖到对应节点下!");
    294                     return;
    295                 }
    296                 var imgItem = imags.FirstOrDefault();
    297                 imgItem.Images.Insert(0, data as ImageTreeControlImageModel);
    298                 imgItem.Parent.NotifyToImagesCount();//图片集合发生变动,发出通知
    299             }
    300             else if (vm_item.Type == ImageTreeControlItemType.Images)
    301             {
    302                 vm_item.Images.Insert(0, data as ImageTreeControlImageModel);
    303                 vm_item.Parent.NotifyToImagesCount();//图片集合发生变动,发出通知
    304             }
    305         }
    306 
    307         /// <summary>
    308         /// 当有数据拖动进来时
    309         /// </summary>
    310         /// <param name="sender"></param>
    311         /// <param name="e"></param>
    312         private void ImageTreeControl_PreviewDragOver(object sender, DragEventArgs e)
    313         {
    314             e.Effects = DragDropEffects.Copy;
    315             e.Handled = e.Data.GetData(typeof(ImageTreeControlImageModel)) != null;
    316         }
    317     }
    318 
    319     internal static class Utils
    320     {
    321         public static T FindVisualParent<T>(DependencyObject obj) where T : class
    322         {
    323             while (obj != null)
    324             {
    325                 if (obj is T)
    326                     return obj as T;
    327 
    328                 obj = VisualTreeHelper.GetParent(obj);
    329             }
    330 
    331             return null;
    332         }
    333     }
    334 }
    View Code

    4、控件datacontext对象

      1 using iPIS.Server.Core;
      2 using iPIS.UI.Base.Model;
      3 using iPIS.UI.Base.Tree;
      4 using iPIS.Utility;
      5 using System;
      6 using System.Collections.Generic;
      7 using System.Collections.ObjectModel;
      8 using System.ComponentModel;
      9 using System.Linq;
     10 using System.Text;
     11 using System.Threading.Tasks;
     12 
     13 namespace iPIS.UI.Base.ViewModel
     14 {
     15     public class ImageTreeControlViewModel : System.ComponentModel.INotifyPropertyChanged
     16     {
     17         public event PropertyChangedEventHandler PropertyChanged;
     18         private ImageTreeControl imageTreeControl;
     19 
     20         public ImageTreeControlViewModel(ImageTreeControl imageTreeControl)
     21         {
     22             this.imageTreeControl = imageTreeControl;
     23         }
     24 
     25         private ObservableCollection<ImageTreeControlItemModelPackage> _DataList = new ObservableCollection<ImageTreeControlItemModelPackage>();
     26 
     27         /// <summary>
     28         /// 数据集合,请使用 函数SetDataList,进行赋值构建
     29         /// </summary>
     30         public ObservableCollection<ImageTreeControlItemModelPackage> DataList
     31         {
     32             get => _DataList;
     33             private set
     34             {
     35                 _DataList = value;
     36                 PropertyChanged?.Notify(() => this.DataList);
     37             }
     38         }
     39 
     40         /// <summary>
     41         /// 视图状态,默认文件名形式
     42         /// 0:文件名称;1:缩略图
     43         /// </summary>
     44         public int ViewState
     45         {
     46             get => imageTreeControl.ImageTreeControlViewState;
     47             set
     48             {
     49                 imageTreeControl.ImageTreeControlViewState = value;
     50             }
     51         }
     52 
     53         /// <summary>
     54         /// 发出数据变更通知通知
     55         /// </summary>
     56         /// <param name="vm"></param>
     57         public void NotifyToDataList()
     58         {
     59             PropertyChanged?.Notify(() => this.DataList);
     60         }
     61 
     62         /// <summary>
     63         /// 选中匹配成功的 text
     64         /// </summary>
     65         /// <param name="text">需要匹配的名称</param>
     66         /// <param name="isfullvalue">true:全值匹配;false:模糊匹配</param>
     67         /// <returns></returns>
     68         public List<object> SelectedItem(string text, bool isfullvalue)
     69         {
     70             if (string.IsNullOrEmpty(text)) return new List<object>(); ;
     71             List<object> outlist = new List<object>();
     72             SetSelected(DataList, text, isfullvalue, outlist);
     73             if (outlist.Count > 0)
     74                 PropertyChanged?.Notify(() => this.DataList);
     75             return outlist;
     76         }
     77 
     78         /// <summary>
     79         /// 选中匹配成功的 id
     80         /// </summary>
     81         /// <param name="Id"></param>
     82         /// <returns></returns>
     83         public object SelectedItem(string Id)
     84         {
     85             if (string.IsNullOrEmpty(Id)) return new { };
     86             object outob = null;
     87             SetSelected(DataList, Id, ref outob);
     88             if (outob != null)
     89                 PropertyChanged?.Notify(() => this.DataList);
     90             return outob;
     91         }
     92 
     93         /// <summary>
     94         /// 获取所有的图片
     95         /// </summary>
     96         /// <param name="imageType">图片类型,默认返回所有类型</param>
     97         /// <returns></returns>
     98         public List<ImageTreeControlImageModel> GetAllImages(ImageTreeControlImageType imageType = ImageTreeControlImageType.None)
     99         {
    100             List<ImageTreeControlImageModel> list = new List<ImageTreeControlImageModel>();
    101             return list;
    102         }
    103 
    104         /// <summary>
    105         /// 设置选中状态
    106         /// </summary>
    107         /// <param name="items"></param>
    108         /// <param name="text"></param>
    109         /// <param name="isfullvalue"></param>
    110         /// <param name="selecteditems"></param>
    111         private void SetSelected(ObservableCollection<ImageTreeControlItemModelPackage> items, string text, bool isfullvalue, List<object> selecteditems = null)
    112         {
    113             if (selecteditems == null) selecteditems = new List<object>();
    114 
    115             foreach (var item in items)
    116             {
    117                 if (item.Type == ImageTreeControlItemType.Classify)
    118                 {
    119                     item.IsSelected = isfullvalue && item.Text.Equals(text) || !isfullvalue && item.Text.Contains(text);
    120                     if (item.IsSelected)
    121                         selecteditems.Add(item);
    122                 }
    123                 else
    124                 {
    125                     foreach (var img in item.Images)
    126                     {
    127                         img.IsSelected = isfullvalue && img.Text.Equals(text) || !isfullvalue && img.Text.Contains(text);
    128                         if (img.IsSelected)
    129                             selecteditems.Add(img);
    130                     }
    131                 }
    132                 SetSelected(item.Children, text, isfullvalue, selecteditems);
    133             }
    134         }
    135 
    136         /// <summary>
    137         /// 设置选中状态
    138         /// </summary>
    139         /// <param name="items"></param>
    140         /// <param name="id"></param>
    141         /// <param name="selecteditem"></param>
    142         private void SetSelected(ObservableCollection<ImageTreeControlItemModelPackage> items, string id, ref object selecteditem)
    143         {
    144             foreach (var item in items)
    145             {
    146                 if (item.Type == ImageTreeControlItemType.Classify)
    147                 {
    148                     item.IsSelected = item.Id.Equals(id);
    149                     if (item.IsSelected)
    150                         selecteditem = item;
    151                 }
    152                 else
    153                 {
    154                     foreach (var img in item.Images)
    155                     {
    156                         img.IsSelected = img.Id.Equals(id);
    157                         if (img.IsSelected)
    158                             selecteditem = img;
    159                     }
    160                 }
    161                 SetSelected(item.Children, id, ref selecteditem);
    162             }
    163         }
    164 
    165         /// <summary>
    166         /// 设置数据源
    167         /// </summary>
    168         /// <param name="items"></param>
    169         public void SetDataList(List<ImageTreeControlItemModel> items)
    170         {
    171             DataList.Clear();
    172             ObservableCollection<ImageTreeControlItemModelPackage> roots = new ObservableCollection<ImageTreeControlItemModelPackage>();
    173             foreach (var item in items)
    174             {
    175                 ImageTreeControlItemModelPackage itemP = new ImageTreeControlItemModelPackage(null);
    176                 itemP.Type = ImageTreeControlItemType.Classify;
    177                 itemP.Id = item.Id;
    178                 itemP.Text = item.Text;
    179                 itemP.Value = item.Value;
    180                 //递归设置子集
    181                 SetChildren(item.Children, itemP);
    182                 //处理图片
    183                 SetImages(item, itemP);
    184                 //设置图标
    185                 itemP.IconSource = item.IconSource;
    186                 //系统内置的root图标给予覆盖
    187                 SetRootIcon(itemP);
    188                 roots.Add(itemP);
    189             }
    190             DataList = roots;
    191         }
    192 
    193         /// <summary>
    194         /// 递归设置子集
    195         /// </summary>
    196         /// <param name="items"></param>
    197         /// <param name="parent"></param>
    198         private void SetChildren(List<ImageTreeControlItemModel> items, ImageTreeControlItemModelPackage parent)
    199         {
    200             if (items == null || items.Count == 0) return;
    201 
    202             foreach (var item in items)
    203             {
    204                 ImageTreeControlItemModelPackage itemP = new ImageTreeControlItemModelPackage(parent);
    205                 itemP.Id = item.Id;
    206                 itemP.Text = item.Text;
    207                 itemP.Value = item.Value;
    208                 //递归设置子集
    209                 SetChildren(item.Children, itemP);
    210                 //处理图片
    211                 SetImages(item, itemP);
    212                 parent.Children.Add(itemP);
    213             }
    214         }
    215 
    216         /// <summary>
    217         /// 设置当前实体的图片集合
    218         /// </summary>
    219         /// <param name="item"></param>
    220         /// <param name="parent"></param>
    221         private void SetImages(ImageTreeControlItemModel item, ImageTreeControlItemModelPackage parent)
    222         {
    223             if (item.Images == null || item.Images.Count == 0) return;
    224 
    225             ImageTreeControlItemModelPackage imgP = new ImageTreeControlItemModelPackage(parent);
    226             imgP.Type = ImageTreeControlItemType.Images;
    227             foreach (var img in item.Images)
    228             {
    229                 imgP.Images.Add(img);
    230             }
    231             parent.Children.Add(imgP);
    232         }
    233 
    234         /// <summary>
    235         /// 设置根节点的图标
    236         /// </summary>
    237         private void SetRootIcon(ImageTreeControlItemModelPackage root)
    238         {
    239             if (root.Parent != null) return;
    240             var fc = root.Value as filecategory;
    241             if (fc == null) return;
    242             if (fc.CategorySource != 1) return;
    243             var url = string.Empty;
    244             switch (fc.CategoryName)
    245             {
    246                 case "头部五官":
    247                     url = PublicMethod.GetSet("Web") + "/Images/ImageCategoryIcons/人像鉴定系统-文书icons正面.png";
    248                     break;
    249                 case "人体动态":
    250                     url = PublicMethod.GetSet("Web") + "/Images/ImageCategoryIcons/人像鉴定系统-文书icons人体动态.png";
    251                     break;
    252                 case "身高":
    253                     url = PublicMethod.GetSet("Web") + "/Images/ImageCategoryIcons/人像鉴定系统-文书icons身高.png";
    254                     break;
    255                 case "特殊标示":
    256                     url = PublicMethod.GetSet("Web") + "/Images/ImageCategoryIcons/人像鉴定系统-文书icons特殊.png";
    257                     break;
    258                 case "衣着配饰":
    259                     url = PublicMethod.GetSet("Web") + "/Images/ImageCategoryIcons/人像鉴定系统-文书icons衣服.png";
    260                     break;
    261                 case "其他":
    262                     break; ;
    263                 default:
    264                     break;
    265             }
    266             if (!string.IsNullOrEmpty(url))
    267                 root.IconSource = new System.Windows.Media.Imaging.BitmapImage(new Uri(url, UriKind.Absolute));
    268         }
    269     }
    270 }
    View Code

    5、数据真实实体

      1 using iPIS.UI.Base.ViewModel;
      2 using System;
      3 using System.Collections.Generic;
      4 using System.Collections.ObjectModel;
      5 using System.ComponentModel;
      6 using System.Linq;
      7 using System.Text;
      8 using System.Threading.Tasks;
      9 using System.Windows.Media.Imaging;
     10 
     11 namespace iPIS.UI.Base.Model
     12 {
     13     /// <summary>
     14     /// 图片树状,子项实体的包装类,请使用 ImageTreeControlItemModel 完成构建
     15     /// </summary>
     16     public class ImageTreeControlItemModelPackage : INotifyPropertyChanged
     17     {
     18 
     19         public event PropertyChangedEventHandler PropertyChanged;
     20         private string _Id = string.Empty;
     21         private bool _IsSelected = false;
     22 
     23         /// <summary>
     24         /// 当前的父级
     25         /// </summary>
     26         /// <param name="Parent">当前元素的父级,null代表无父级,顶层元素</param>
     27         public ImageTreeControlItemModelPackage(ImageTreeControlItemModelPackage Parent)
     28         {
     29             this.Parent = Parent;
     30         }
     31 
     32         /// <summary>
     33         /// 唯一标示
     34         /// </summary>
     35         public string Id
     36         {
     37             get
     38             {
     39                 if (string.IsNullOrEmpty(_Id)) _Id = Guid.NewGuid().ToString();
     40                 return _Id;
     41             }
     42             set => _Id = value;
     43         }
     44 
     45         /// <summary>
     46         /// 当前类型
     47         /// </summary>
     48         public ImageTreeControlItemType Type { get; set; } = ImageTreeControlItemType.Classify;
     49 
     50         /// <summary>
     51         /// 分类名称,type=Classify 时有效
     52         /// </summary>
     53         public string Text { get; set; }
     54 
     55         /// <summary>
     56         /// 绑定值
     57         /// </summary>
     58         public object Value { get; set; }
     59 
     60         /// <summary>
     61         /// 分类图标,type=Classify 时有效
     62         /// </summary>
     63         public BitmapImage IconSource { get; set; } = null;
     64 
     65         /// <summary>
     66         /// 所属的集合,type=Classify 时有效
     67         /// </summary>
     68         public ObservableCollection<ImageTreeControlItemModelPackage> Children { get; set; } = new ObservableCollection<ImageTreeControlItemModelPackage>();
     69 
     70         /// <summary>
     71         /// 当前的父级
     72         /// </summary>
     73         public ImageTreeControlItemModelPackage Parent { get; set; }
     74 
     75         /// <summary>
     76         /// 所属的图片集合,type=Images 时有效
     77         /// UI已经构建的模块,新增插入编辑集合,请使用帮助函数
     78         /// </summary>
     79         public ObservableCollection<ImageTreeControlImageModel> Images { get; set; } = new ObservableCollection<ImageTreeControlImageModel>();
     80 
     81         /// <summary>
     82         /// 当前下的图片集合,type=Classify 时有效
     83         /// </summary>
     84         public ObservableCollection<ImageTreeControlImageModel> GetImages
     85         {
     86             get
     87             {
     88                 if (Type == ImageTreeControlItemType.Images)
     89                     return new ObservableCollection<ImageTreeControlImageModel>();
     90                 ObservableCollection<ImageTreeControlImageModel> list = new ObservableCollection<ImageTreeControlImageModel>();
     91                 foreach (var item in Children.Where(c => c.Type == ImageTreeControlItemType.Images))
     92                 {
     93                     foreach (var img in item.Images)
     94                     {
     95                         list.Add(img);
     96                     }
     97                 }
     98                 return list;
     99             }
    100         }
    101 
    102         /// <summary>
    103         /// 是否选中
    104         /// </summary>
    105         public bool IsSelected
    106         {
    107             get
    108             {
    109                 return _IsSelected;
    110             }
    111             set
    112             {
    113                 _IsSelected = value;
    114                 PropertyChanged?.Notify(() => this.IsSelected);
    115             }
    116         }
    117 
    118         /// <summary>
    119         /// 当前下的图片集合数量,type=Classify 时有效
    120         /// </summary>
    121         public int ImagesCount
    122         {
    123             get => GetImages.Count;
    124         }
    125 
    126         /// <summary>
    127         /// 当前下的图片集合数量,type=Classify 时有效
    128         /// </summary>
    129         public void NotifyToImagesCount()
    130         {
    131             if (Type == ImageTreeControlItemType.Classify)
    132                 PropertyChanged?.Notify(() => this.ImagesCount);
    133         }
    134     }
    135 
    136     /// <summary>
    137     /// 图片树状,所属子项的图片实体
    138     /// </summary>
    139     public class ImageTreeControlImageModel : INotifyPropertyChanged
    140     {
    141         public event PropertyChangedEventHandler PropertyChanged;
    142         private string _Id = string.Empty;
    143         private bool _IsSelected = false;
    144         private ImageTreeControlImageType _Type = ImageTreeControlImageType.Default;
    145 
    146         /// <summary>
    147         /// 唯一标示
    148         /// </summary>
    149         public string Id
    150         {
    151             get
    152             {
    153                 if (string.IsNullOrEmpty(_Id)) _Id = Guid.NewGuid().ToString();
    154                 return _Id;
    155             }
    156             set => _Id = value;
    157         }
    158 
    159         /// <summary>
    160         /// 图片名称
    161         /// </summary>
    162         public string Text { get; set; }
    163 
    164         /// <summary>
    165         /// 绑定值
    166         /// </summary>
    167         public object Value { get; set; }
    168 
    169         /// <summary>
    170         /// 图片资源
    171         /// </summary>
    172         public BitmapImage ImageSource { get; set; } = null;
    173 
    174         /// <summary>
    175         /// 图片类型
    176         /// </summary>
    177         public ImageTreeControlImageType Type
    178         {
    179             get
    180             {
    181                 return _Type;
    182             }
    183             set
    184             {
    185                 _Type = value;
    186                 PropertyChanged?.Notify(() => this.Type);
    187             }
    188         }
    189 
    190         /// <summary>
    191         /// 是否选中
    192         /// </summary>
    193         public bool IsSelected
    194         {
    195             get
    196             {
    197                 return _IsSelected;
    198             }
    199             set
    200             {
    201                 _IsSelected = value;
    202                 PropertyChanged?.Notify(() => this.IsSelected);
    203             }
    204         }
    205     }
    206 
    207     /// <summary>
    208     /// 图片树状,子项类型
    209     /// </summary>
    210     public enum ImageTreeControlItemType
    211     {
    212         /// <summary>
    213         /// 分类
    214         /// </summary>
    215         Classify = 0,
    216         /// <summary>
    217         /// 图片资源
    218         /// </summary>
    219         Images = 1
    220     }
    221 
    222     /// <summary>
    223     /// 图片树状,所属子项的图片的类型
    224     /// </summary>
    225     public enum ImageTreeControlImageType
    226     {
    227         /// <summary>
    228         /// 什么也不是
    229         /// </summary>
    230         None = -1,
    231         /// <summary>
    232         /// 默认
    233         /// </summary>
    234         Default = 0,
    235         /// <summary>
    236         /// 抠图
    237         /// </summary>
    238         Matting = 1,
    239         /// <summary>
    240         /// 已经对此抠图了
    241         /// </summary>
    242         AlreadyMatting = 2
    243     }
    244 }
    View Code

    6、调用者关心的数据实体(因为绑定数据构建有点麻烦,所以封装了下,使调用者不关心复杂逻辑)

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 using System.Windows.Media.Imaging;
     7 
     8 namespace iPIS.UI.Base.Model
     9 {
    10     /// <summary>
    11     /// 图片树状,子项实体
    12     /// </summary>
    13     public class ImageTreeControlItemModel
    14     {
    15         /// <summary>
    16         /// 唯一标示符
    17         /// </summary>
    18         public string Id { get; set; }
    19 
    20         /// <summary>
    21         /// 显示名称
    22         /// </summary>
    23         public string Text { get; set; }
    24 
    25         /// <summary>
    26         /// 绑定值
    27         /// </summary>
    28         public object Value { get; set; }
    29 
    30         /// <summary>
    31         /// 当前的下级
    32         /// </summary>
    33         public List<ImageTreeControlItemModel> Children { get; set; }
    34 
    35         /// <summary>
    36         /// 当前节点下的图片集合
    37         /// </summary>
    38         public List<ImageTreeControlImageModel> Images { get; set; }
    39 
    40         /// <summary>
    41         /// 类别显示图标
    42         /// </summary>
    43         public BitmapImage IconSource { get; set; } = null;
    44     }
    45 }
    View Code

    好了,该控件的全部代码已经看完了,下面我就把我遇到的问题进行按个阐述,且附上解决方案

    1、首要问题就是如何才能节点下面再批量显示图片

    答:通过假节点来实现,每个节点绑定一个Type类型,标示当前是节点还是节点下的图片显示,如果是节点下的图片,该节点不显示头,显示下面的图片集合

    附上关键代码

    2、如何缩略图和文件列表的动图切换

    答:起初考虑这个属性设置在datacontext还是控件里,最开始是想放在datacontext里的,但是,UI上的绑定出了问题,找了几圈没得合适的解决办法,迫于无奈就放在控件里了,通过附加属性控制,细心的朋友应该会发现是利用的多条件的触发器,因为需要首先满足当前节点是图片集合的容器,详情可参照问题1

    附上关键代码

    3、调用者需要动态的设置选中

    答:通过数据实体继承INotifyPropertyChanged接口,实现通知即可实现;特别说明,因为在vm里面只能对数据集发起变更的通知,所以数据源发送的变动需要自助发起通知,子集会自动更新的,至于原理我也不是很清楚,反正不通知就没戏,亲测

    附上关键代码

    4、因为实现了拖住,允许接收外界的数据,需要动态载入节点中,如何更新UI和更新父级节点的统计数量

    答:实现原理和问题3差不多,需要提醒的是,由于集合发生变动,需要发起通知才行,否则是不会更新的,请看关键代码

    附上关键代码

     5、由于数据结果过于复杂,调用是无需关心的,所以需要给调用者提供简易的数据构建函数

    答:数据源的赋值访问设置为私有,杜绝外部写入,通过公开函数构建

    附上关键代码

  • 相关阅读:
    Python正课15 —— 流程控制之while循环
    Python正课14 —— 深浅Copy
    Python正课13 —— 流程控制之if判断
    Python正课12 —— 成员运算 与 身份运算
    Python正课11 —— 逻辑运算
    Python正课10 —— 条件
    Python正课9 —— 可变不可变类型
    Python正课8 —— 运算符
    Python正课7 —— 与用户交互
    Python正课6 —— 垃圾回收机制
  • 原文地址:https://www.cnblogs.com/xuling-297769461/p/9328335.html
Copyright © 2020-2023  润新知