1、先看下整体效果

2、前端代码

 <UserControl x:Class="iPIS.UI.Base.Tree.ImageTreeControl"
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:local="clr-namespace:iPIS.UI.Base.Tree"
mc:Ignorable="d"
d:DesignHeight="45" d:DesignWidth="80">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/iPIS.UI.Themes.Black;component/Base/Tree/VideoTreeControlImages.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="TextBlock" x:Key="treename">
<Setter Property="Foreground" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ImageTreeControlFontColor}"></Setter>
<Setter Property="FontSize" Value="14"></Setter>
</Style>
</ResourceDictionary>
</UserControl.Resources>
<TreeView x:Name="tree"
ItemsSource="{Binding DataList}"
Background="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ImageTreeControlBackground}"
>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<Grid Margin="-1 0 0 0"
Cursor="Hand"
Background="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ImageTreeControlBackground}"
>
<StackPanel x:Name="Classify" Orientation="Horizontal">
<Image Source="{Binding IconSource}"
Width="25"
Height="25"
VerticalAlignment="Center"
Margin="0 0 10 0"
></Image>
<TextBlock Text="{Binding Text}"
VerticalAlignment="Center"
Style="{StaticResource treename}">
</TextBlock>
<TextBlock Style="{StaticResource treename}"
VerticalAlignment="Center"
>(</TextBlock>
<TextBlock Text="{Binding ImagesCount}"
VerticalAlignment="Center"
Style="{StaticResource treename}"
></TextBlock>
<TextBlock Style="{StaticResource treename}"
VerticalAlignment="Center"
>)</TextBlock>
</StackPanel>
<!--缩略图视图-->
<ListBox x:Name="Image_slt"
ItemsSource="{Binding Images}"
Visibility="Collapsed"
Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ThumbnailWidth}"
Background="Transparent"
Margin="-35 0 0 0"
>
<ListBox.Template>
<ControlTemplate TargetType="{x:Type ListBox}">
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
<WrapPanel Orientation="Horizontal" IsItemsHost="True"></WrapPanel>
</ScrollViewer>
</ControlTemplate>
</ListBox.Template>
<ListBox.ItemTemplate>
<DataTemplate>
<Border x:Name="border"
BorderBrush="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ImageTreeControlImageBoderColor}"
Background="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ImageTreeControlImageBoderColor}"
BorderThickness="3"
Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ImageTreeControlImageWidth}"
Height="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ImageTreeControlImageHeight}"
>
<Grid>
<Image Source="{Binding ImageSource}"
Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ImageTreeControlImageWidth}"
Height="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ImageTreeControlImageHeight}"
></Image>
<Image x:Name="icon" Visibility="Collapsed" Width="13" Height="14" Margin="-72 -50 0 0"></Image>
</Grid>
</Border>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Type}" Value="1">
<Setter TargetName="icon" Property="Visibility" Value="Visible"></Setter>
<Setter TargetName="icon" Property="Source" Value="{StaticResource icon_kou}"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Type}" Value="2">
<Setter TargetName="icon" Property="Visibility" Value="Visible"></Setter>
<Setter TargetName="icon" Property="Source" Value="{StaticResource icon_jiandao}"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding IsSelected}" Value="true">
<Setter TargetName="border"
Property="BorderBrush"
Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ImageTreeControlImageSelectedBoderColor}"
></Setter>
</DataTrigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="border"
Property="BorderBrush"
Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ImageTreeControlImageMouseOverBoderColor}"
></Setter>
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Padding" Value="0"></Setter>
<Setter Property="BorderThickness" Value="0"></Setter>
<Setter Property="Margin" Value="1"></Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
<!--文件名视图-->
<ListBox x:Name="Image_file"
ItemsSource="{Binding Images}"
BorderThickness="0"
Background="Transparent"
Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ListWidth}"
Margin="-35 0 0 0"
>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock x:Name="text"
Text="{Binding Text}"
Foreground="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ImageTreeControlImageImgNameColor}"
></TextBlock>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsSelected}" Value="true">
<Setter TargetName="text"
Property="Foreground"
Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ImageTreeControlImageSelectedImgNameColor}"
></Setter>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
<HierarchicalDataTemplate.Triggers>
<DataTrigger Binding="{Binding Type}" Value="0">
<Setter TargetName="Classify" Property="Visibility" Value="Visible"></Setter>
<Setter TargetName="Image_slt" Property="Visibility" Value="Collapsed"></Setter>
<Setter TargetName="Image_file" Property="Visibility" Value="Collapsed"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Type}" Value="1">
<Setter TargetName="Classify" Property="Visibility" Value="Collapsed"></Setter>
</DataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Type}" Value="1"></Condition>
<Condition Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ImageTreeControlViewState}" Value="0"></Condition>
</MultiDataTrigger.Conditions>
<Setter TargetName="Image_slt" Property="Visibility" Value="Collapsed"></Setter>
<Setter TargetName="Image_file" Property="Visibility" Value="Visible"></Setter>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Type}" Value="1"></Condition>
<Condition Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:ImageTreeControl},Path=ImageTreeControlViewState}" Value="1"></Condition>
</MultiDataTrigger.Conditions>
<Setter TargetName="Image_slt" Property="Visibility" Value="Visible"></Setter>
<Setter TargetName="Image_file" Property="Visibility" Value="Collapsed"></Setter>
</MultiDataTrigger>
</HierarchicalDataTemplate.Triggers> </HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</UserControl>

3、控件后台代码

 using iPIS.UI.Base.Model;
using iPIS.UI.Base.ViewModel;
using iPIS.Utility;
using System;
using System.Collections.Generic;
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 iPIS.UI.Base.Tree
{
/// <summary>
/// ImageTreeControl.xaml 的交互逻辑
/// </summary>
public partial class ImageTreeControl : UserControl
{
public ImageTreeControl()
{
InitializeComponent();
var vm = new ImageTreeControlViewModel(this);
this.DataContext = vm;
this.PreviewDragOver += ImageTreeControl_PreviewDragOver;
this.PreviewDrop += ImageTreeControl_PreviewDrop;
this.SizeChanged += ImageTreeControl_SizeChanged; //默认样式
ImageTreeControlViewState = ;
ImageTreeControlImageWidth = ;
ImageTreeControlImageHeight = ;
ImageTreeControlBackground = "#36353a";
ImageTreeControlFontColor = "#89888d";
ImageTreeControlImageBoderColor = "#000000";
ImageTreeControlImageSelectedBoderColor = "#019e97";
ImageTreeControlImageMouseOverBoderColor = ImageTreeControlImageSelectedBoderColor;
ImageTreeControlImageImgNameColor = ImageTreeControlFontColor;
ImageTreeControlImageSelectedImgNameColor = ImageTreeControlImageSelectedBoderColor; //测试数据
test();
} /// <summary>
/// 大小发送变化时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ImageTreeControl_SizeChanged(object sender, SizeChangedEventArgs e)
{
ThumbnailWidth = (int)this.Width - ;
ListWidth = (int)this.Width - ;
} private void test()
{
//模拟数据
var list = new Client.WebApiWrap.PVL.FileCategoryApiWrap().GetFileCategoryList("ac165316-6630-40ba-84bb-fba75475d713", , , -, );
var datas = new List<ImageTreeControlItemModel>();
for (int j = ; j < list.Count; j++)
{
var item = list[j];
ImageTreeControlItemModel root = new ImageTreeControlItemModel();
root.Text = item.CategoryName;
root.Value = item;
root.Images = new List<ImageTreeControlImageModel>();
for (int i = ; i < ; i++)
{
root.Images.Add(new ImageTreeControlImageModel()
{
ImageSource = new BitmapImage(new Uri(PublicMethod.GetSet("Web") + "/images/defaut.png")),
Text = "我是名称"
});
}
if (j == list.Count - )
{
ImageTreeControlItemModel m = new ImageTreeControlItemModel();
m.Text = "我是第二级";
m.Images = new List<ImageTreeControlImageModel>();
for (int i = ; i < ; i++)
{
m.Images.Add(new ImageTreeControlImageModel()
{
ImageSource = new BitmapImage(new Uri(PublicMethod.GetSet("Web") + "/images/defaut.png")),
Text = "我是第二级的图片"
});
}
root.Children = new List<ImageTreeControlItemModel>() { m };
}
datas.Add(root);
}
vm.SetDataList(datas);
} /// <summary>
/// 上下文
/// </summary>
public ImageTreeControlViewModel vm
{
get
{
return this.DataContext as ImageTreeControlViewModel;
}
} /// <summary>
/// 背景色
/// </summary>
public string ImageTreeControlBackground
{
get { return (string)GetValue(ImageTreeControlBackgroundProperty); }
set { SetValue(ImageTreeControlBackgroundProperty, value); }
} /// <summary>
/// 视图状态,默认文件名形式
/// 0:文件名称;1:缩略图
/// </summary>
public int ImageTreeControlViewState
{
get { return (int)GetValue(ImageTreeControlViewStateProperty); }
set { SetValue(ImageTreeControlViewStateProperty, value); }
} /// <summary>
/// 缩略图模式,显示的图片宽度
/// </summary>
public int ImageTreeControlImageWidth
{
get { return (int)GetValue(ImageTreeControlImageWidthProperty); }
set { SetValue(ImageTreeControlImageWidthProperty, value); }
} /// <summary>
/// 缩略图模式,显示的图片高度
/// </summary>
public int ImageTreeControlImageHeight
{
get { return (int)GetValue(ImageTreeControlImageHeightProperty); }
set { SetValue(ImageTreeControlImageHeightProperty, value); }
} /// <summary>
/// 树状控件的节点名称字体样式
/// </summary>
public string ImageTreeControlFontColor
{
get { return (string)GetValue(ImageTreeControlFontColorProperty); }
set { SetValue(ImageTreeControlFontColorProperty, value); }
} /// <summary>
/// 默认状态下,图片的边框样式
/// </summary>
public string ImageTreeControlImageBoderColor
{
get { return (string)GetValue(ImageTreeControlImageBoderColorProperty); }
set { SetValue(ImageTreeControlImageBoderColorProperty, value); }
} /// <summary>
/// 缩略图模式的容器宽度
/// </summary>
public int ThumbnailWidth
{
get { return (int)GetValue(ThumbnailWidthProperty); }
private set { SetValue(ThumbnailWidthProperty, value); }
} /// <summary>
/// 文件名称视图的容器宽度
/// </summary>
public int ListWidth
{
get { return (int)GetValue(ListWidthProperty); }
private set { SetValue(ListWidthProperty, value); }
} /// <summary>
/// 选中状态下,图片边框的样式
/// </summary>
public string ImageTreeControlImageSelectedBoderColor
{
get { return (string)GetValue(ImageTreeControlImageSelectedBoderColorProperty); }
set { SetValue(ImageTreeControlImageSelectedBoderColorProperty, value); }
} /// <summary>
/// 鼠标悬浮图片上,图片边框的样式
/// </summary>
public string ImageTreeControlImageMouseOverBoderColor
{
get { return (string)GetValue(ImageTreeControlImageMouseOverBoderColorProperty); }
set { SetValue(ImageTreeControlImageMouseOverBoderColorProperty, value); }
} /// <summary>
/// 默认状态,列表模式,图片名称的样式
/// </summary>
public string ImageTreeControlImageImgNameColor
{
get { return (string)GetValue(ImageTreeControlImageImgNameColorProperty); }
set { SetValue(ImageTreeControlImageImgNameColorProperty, value); }
} /// <summary>
/// 选中状态下,列表模式,图片名称的样式
/// </summary>
public string ImageTreeControlImageSelectedImgNameColor
{
get { return (string)GetValue(ImageTreeControlImageSelectedImgNameColorProperty); }
set { SetValue(ImageTreeControlImageSelectedImgNameColorProperty, value); }
} #region 附加属性 public static readonly DependencyProperty ListWidthProperty =
DependencyProperty.Register("ListWidth", typeof(int), typeof(ImageTreeControl), new PropertyMetadata()); public static readonly DependencyProperty ThumbnailWidthProperty =
DependencyProperty.Register("ThumbnailWidth", typeof(int), typeof(ImageTreeControl), new PropertyMetadata()); public static readonly DependencyProperty ImageTreeControlImageMouseOverBoderColorProperty =
DependencyProperty.Register("ImageTreeControlImageMouseOverBoderColor", typeof(string), typeof(ImageTreeControl), new PropertyMetadata("")); public static readonly DependencyProperty ImageTreeControlImageImgNameColorProperty =
DependencyProperty.Register("ImageTreeControlImageImgNameColor", typeof(string), typeof(ImageTreeControl), new PropertyMetadata("")); public static readonly DependencyProperty ImageTreeControlImageSelectedImgNameColorProperty =
DependencyProperty.Register("ImageTreeControlImageSelectedImgNameColor", typeof(string), typeof(ImageTreeControl), new PropertyMetadata("")); public static readonly DependencyProperty ImageTreeControlImageSelectedBoderColorProperty =
DependencyProperty.Register("ImageTreeControlImageSelectedBoderColor", typeof(string), typeof(ImageTreeControl), new PropertyMetadata("")); public static readonly DependencyProperty ImageTreeControlImageBoderColorProperty =
DependencyProperty.Register("ImageTreeControlImageBoderColor", typeof(string), typeof(ImageTreeControl), new PropertyMetadata("")); public static readonly DependencyProperty ImageTreeControlFontColorProperty =
DependencyProperty.Register("ImageTreeControlFontColor", typeof(string), typeof(ImageTreeControl), new PropertyMetadata("")); public static readonly DependencyProperty ImageTreeControlImageHeightProperty =
DependencyProperty.Register("ImageTreeControlImageHeight", typeof(int), typeof(ImageTreeControl), new PropertyMetadata()); public static readonly DependencyProperty ImageTreeControlImageWidthProperty =
DependencyProperty.Register("ImageTreeControlImageWidth", typeof(int), typeof(ImageTreeControl), new PropertyMetadata()); public static readonly DependencyProperty ImageTreeControlViewStateProperty =
DependencyProperty.Register("ImageTreeControlViewState", typeof(int), typeof(ImageTreeControl), new PropertyMetadata()); public static readonly DependencyProperty ImageTreeControlBackgroundProperty =
DependencyProperty.Register("ImageTreeControlBackground", typeof(string), typeof(ImageTreeControl), new PropertyMetadata("")); #endregion /// <summary>
/// 拖进来了
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ImageTreeControl_PreviewDrop(object sender, DragEventArgs e)
{
var data = e.Data.GetData(typeof(ImageTreeControlImageModel));
if (data == null) return;
Point point = e.GetPosition(tree);
HitTestResult result = VisualTreeHelper.HitTest(tree, point);
if (result == null)
return;
TreeViewItem treeitem = Utils.FindVisualParent<TreeViewItem>(result.VisualHit);
if (treeitem == null)
return;
var vm_item = treeitem.DataContext as ImageTreeControlItemModelPackage;
if (vm_item == null)
return;
if (vm_item.Type == ImageTreeControlItemType.Classify)
{
var imags = vm_item.Children.Where(c => c.Type == ImageTreeControlItemType.Images).ToList();
if (imags.Count == )
{
ImageTreeControlItemModelPackage item = new ImageTreeControlItemModelPackage(vm_item);
item.Type = ImageTreeControlItemType.Images;
vm_item.Children.Add(item);
imags = vm_item.Children.Where(c => c.Type == ImageTreeControlItemType.Images).ToList();
}
else if (imags.Count > )
{
MessageBox.Show("抱歉,当前节点下面有多个子集,无法确定你想存放的位置,请拖到对应节点下!");
return;
}
var imgItem = imags.FirstOrDefault();
imgItem.Images.Insert(, data as ImageTreeControlImageModel);
imgItem.Parent.NotifyToImagesCount();//图片集合发生变动,发出通知
}
else if (vm_item.Type == ImageTreeControlItemType.Images)
{
vm_item.Images.Insert(, data as ImageTreeControlImageModel);
vm_item.Parent.NotifyToImagesCount();//图片集合发生变动,发出通知
}
} /// <summary>
/// 当有数据拖动进来时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ImageTreeControl_PreviewDragOver(object sender, DragEventArgs e)
{
e.Effects = DragDropEffects.Copy;
e.Handled = e.Data.GetData(typeof(ImageTreeControlImageModel)) != null;
}
} internal static class Utils
{
public static T FindVisualParent<T>(DependencyObject obj) where T : class
{
while (obj != null)
{
if (obj is T)
return obj as T; obj = VisualTreeHelper.GetParent(obj);
} return null;
}
}
}

4、控件datacontext对象

 using iPIS.Server.Core;
using iPIS.UI.Base.Model;
using iPIS.UI.Base.Tree;
using iPIS.Utility;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace iPIS.UI.Base.ViewModel
{
public class ImageTreeControlViewModel : System.ComponentModel.INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private ImageTreeControl imageTreeControl; public ImageTreeControlViewModel(ImageTreeControl imageTreeControl)
{
this.imageTreeControl = imageTreeControl;
} private ObservableCollection<ImageTreeControlItemModelPackage> _DataList = new ObservableCollection<ImageTreeControlItemModelPackage>(); /// <summary>
/// 数据集合,请使用 函数SetDataList,进行赋值构建
/// </summary>
public ObservableCollection<ImageTreeControlItemModelPackage> DataList
{
get => _DataList;
private set
{
_DataList = value;
PropertyChanged?.Notify(() => this.DataList);
}
} /// <summary>
/// 视图状态,默认文件名形式
/// 0:文件名称;1:缩略图
/// </summary>
public int ViewState
{
get => imageTreeControl.ImageTreeControlViewState;
set
{
imageTreeControl.ImageTreeControlViewState = value;
}
} /// <summary>
/// 发出数据变更通知通知
/// </summary>
/// <param name="vm"></param>
public void NotifyToDataList()
{
PropertyChanged?.Notify(() => this.DataList);
} /// <summary>
/// 选中匹配成功的 text
/// </summary>
/// <param name="text">需要匹配的名称</param>
/// <param name="isfullvalue">true:全值匹配;false:模糊匹配</param>
/// <returns></returns>
public List<object> SelectedItem(string text, bool isfullvalue)
{
if (string.IsNullOrEmpty(text)) return new List<object>(); ;
List<object> outlist = new List<object>();
SetSelected(DataList, text, isfullvalue, outlist);
if (outlist.Count > )
PropertyChanged?.Notify(() => this.DataList);
return outlist;
} /// <summary>
/// 选中匹配成功的 id
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
public object SelectedItem(string Id)
{
if (string.IsNullOrEmpty(Id)) return new { };
object outob = null;
SetSelected(DataList, Id, ref outob);
if (outob != null)
PropertyChanged?.Notify(() => this.DataList);
return outob;
} /// <summary>
/// 获取所有的图片
/// </summary>
/// <param name="imageType">图片类型,默认返回所有类型</param>
/// <returns></returns>
public List<ImageTreeControlImageModel> GetAllImages(ImageTreeControlImageType imageType = ImageTreeControlImageType.None)
{
List<ImageTreeControlImageModel> list = new List<ImageTreeControlImageModel>();
return list;
} /// <summary>
/// 设置选中状态
/// </summary>
/// <param name="items"></param>
/// <param name="text"></param>
/// <param name="isfullvalue"></param>
/// <param name="selecteditems"></param>
private void SetSelected(ObservableCollection<ImageTreeControlItemModelPackage> items, string text, bool isfullvalue, List<object> selecteditems = null)
{
if (selecteditems == null) selecteditems = new List<object>(); foreach (var item in items)
{
if (item.Type == ImageTreeControlItemType.Classify)
{
item.IsSelected = isfullvalue && item.Text.Equals(text) || !isfullvalue && item.Text.Contains(text);
if (item.IsSelected)
selecteditems.Add(item);
}
else
{
foreach (var img in item.Images)
{
img.IsSelected = isfullvalue && img.Text.Equals(text) || !isfullvalue && img.Text.Contains(text);
if (img.IsSelected)
selecteditems.Add(img);
}
}
SetSelected(item.Children, text, isfullvalue, selecteditems);
}
} /// <summary>
/// 设置选中状态
/// </summary>
/// <param name="items"></param>
/// <param name="id"></param>
/// <param name="selecteditem"></param>
private void SetSelected(ObservableCollection<ImageTreeControlItemModelPackage> items, string id, ref object selecteditem)
{
foreach (var item in items)
{
if (item.Type == ImageTreeControlItemType.Classify)
{
item.IsSelected = item.Id.Equals(id);
if (item.IsSelected)
selecteditem = item;
}
else
{
foreach (var img in item.Images)
{
img.IsSelected = img.Id.Equals(id);
if (img.IsSelected)
selecteditem = img;
}
}
SetSelected(item.Children, id, ref selecteditem);
}
} /// <summary>
/// 设置数据源
/// </summary>
/// <param name="items"></param>
public void SetDataList(List<ImageTreeControlItemModel> items)
{
DataList.Clear();
ObservableCollection<ImageTreeControlItemModelPackage> roots = new ObservableCollection<ImageTreeControlItemModelPackage>();
foreach (var item in items)
{
ImageTreeControlItemModelPackage itemP = new ImageTreeControlItemModelPackage(null);
itemP.Type = ImageTreeControlItemType.Classify;
itemP.Id = item.Id;
itemP.Text = item.Text;
itemP.Value = item.Value;
//递归设置子集
SetChildren(item.Children, itemP);
//处理图片
SetImages(item, itemP);
//设置图标
itemP.IconSource = item.IconSource;
//系统内置的root图标给予覆盖
SetRootIcon(itemP);
roots.Add(itemP);
}
DataList = roots;
} /// <summary>
/// 递归设置子集
/// </summary>
/// <param name="items"></param>
/// <param name="parent"></param>
private void SetChildren(List<ImageTreeControlItemModel> items, ImageTreeControlItemModelPackage parent)
{
if (items == null || items.Count == ) return; foreach (var item in items)
{
ImageTreeControlItemModelPackage itemP = new ImageTreeControlItemModelPackage(parent);
itemP.Id = item.Id;
itemP.Text = item.Text;
itemP.Value = item.Value;
//递归设置子集
SetChildren(item.Children, itemP);
//处理图片
SetImages(item, itemP);
parent.Children.Add(itemP);
}
} /// <summary>
/// 设置当前实体的图片集合
/// </summary>
/// <param name="item"></param>
/// <param name="parent"></param>
private void SetImages(ImageTreeControlItemModel item, ImageTreeControlItemModelPackage parent)
{
if (item.Images == null || item.Images.Count == ) return; ImageTreeControlItemModelPackage imgP = new ImageTreeControlItemModelPackage(parent);
imgP.Type = ImageTreeControlItemType.Images;
foreach (var img in item.Images)
{
imgP.Images.Add(img);
}
parent.Children.Add(imgP);
} /// <summary>
/// 设置根节点的图标
/// </summary>
private void SetRootIcon(ImageTreeControlItemModelPackage root)
{
if (root.Parent != null) return;
var fc = root.Value as filecategory;
if (fc == null) return;
if (fc.CategorySource != ) return;
var url = string.Empty;
switch (fc.CategoryName)
{
case "头部五官":
url = PublicMethod.GetSet("Web") + "/Images/ImageCategoryIcons/人像鉴定系统-文书icons正面.png";
break;
case "人体动态":
url = PublicMethod.GetSet("Web") + "/Images/ImageCategoryIcons/人像鉴定系统-文书icons人体动态.png";
break;
case "身高":
url = PublicMethod.GetSet("Web") + "/Images/ImageCategoryIcons/人像鉴定系统-文书icons身高.png";
break;
case "特殊标示":
url = PublicMethod.GetSet("Web") + "/Images/ImageCategoryIcons/人像鉴定系统-文书icons特殊.png";
break;
case "衣着配饰":
url = PublicMethod.GetSet("Web") + "/Images/ImageCategoryIcons/人像鉴定系统-文书icons衣服.png";
break;
case "其他":
break; ;
default:
break;
}
if (!string.IsNullOrEmpty(url))
root.IconSource = new System.Windows.Media.Imaging.BitmapImage(new Uri(url, UriKind.Absolute));
}
}
}

5、数据真实实体

 using iPIS.UI.Base.ViewModel;
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.Media.Imaging; namespace iPIS.UI.Base.Model
{
/// <summary>
/// 图片树状,子项实体的包装类,请使用 ImageTreeControlItemModel 完成构建
/// </summary>
public class ImageTreeControlItemModelPackage : INotifyPropertyChanged
{ public event PropertyChangedEventHandler PropertyChanged;
private string _Id = string.Empty;
private bool _IsSelected = false; /// <summary>
/// 当前的父级
/// </summary>
/// <param name="Parent">当前元素的父级,null代表无父级,顶层元素</param>
public ImageTreeControlItemModelPackage(ImageTreeControlItemModelPackage Parent)
{
this.Parent = Parent;
} /// <summary>
/// 唯一标示
/// </summary>
public string Id
{
get
{
if (string.IsNullOrEmpty(_Id)) _Id = Guid.NewGuid().ToString();
return _Id;
}
set => _Id = value;
} /// <summary>
/// 当前类型
/// </summary>
public ImageTreeControlItemType Type { get; set; } = ImageTreeControlItemType.Classify; /// <summary>
/// 分类名称,type=Classify 时有效
/// </summary>
public string Text { get; set; } /// <summary>
/// 绑定值
/// </summary>
public object Value { get; set; } /// <summary>
/// 分类图标,type=Classify 时有效
/// </summary>
public BitmapImage IconSource { get; set; } = null; /// <summary>
/// 所属的集合,type=Classify 时有效
/// </summary>
public ObservableCollection<ImageTreeControlItemModelPackage> Children { get; set; } = new ObservableCollection<ImageTreeControlItemModelPackage>(); /// <summary>
/// 当前的父级
/// </summary>
public ImageTreeControlItemModelPackage Parent { get; set; } /// <summary>
/// 所属的图片集合,type=Images 时有效
/// UI已经构建的模块,新增插入编辑集合,请使用帮助函数
/// </summary>
public ObservableCollection<ImageTreeControlImageModel> Images { get; set; } = new ObservableCollection<ImageTreeControlImageModel>(); /// <summary>
/// 当前下的图片集合,type=Classify 时有效
/// </summary>
public ObservableCollection<ImageTreeControlImageModel> GetImages
{
get
{
if (Type == ImageTreeControlItemType.Images)
return new ObservableCollection<ImageTreeControlImageModel>();
ObservableCollection<ImageTreeControlImageModel> list = new ObservableCollection<ImageTreeControlImageModel>();
foreach (var item in Children.Where(c => c.Type == ImageTreeControlItemType.Images))
{
foreach (var img in item.Images)
{
list.Add(img);
}
}
return list;
}
} /// <summary>
/// 是否选中
/// </summary>
public bool IsSelected
{
get
{
return _IsSelected;
}
set
{
_IsSelected = value;
PropertyChanged?.Notify(() => this.IsSelected);
}
} /// <summary>
/// 当前下的图片集合数量,type=Classify 时有效
/// </summary>
public int ImagesCount
{
get => GetImages.Count;
} /// <summary>
/// 当前下的图片集合数量,type=Classify 时有效
/// </summary>
public void NotifyToImagesCount()
{
if (Type == ImageTreeControlItemType.Classify)
PropertyChanged?.Notify(() => this.ImagesCount);
}
} /// <summary>
/// 图片树状,所属子项的图片实体
/// </summary>
public class ImageTreeControlImageModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _Id = string.Empty;
private bool _IsSelected = false;
private ImageTreeControlImageType _Type = ImageTreeControlImageType.Default; /// <summary>
/// 唯一标示
/// </summary>
public string Id
{
get
{
if (string.IsNullOrEmpty(_Id)) _Id = Guid.NewGuid().ToString();
return _Id;
}
set => _Id = value;
} /// <summary>
/// 图片名称
/// </summary>
public string Text { get; set; } /// <summary>
/// 绑定值
/// </summary>
public object Value { get; set; } /// <summary>
/// 图片资源
/// </summary>
public BitmapImage ImageSource { get; set; } = null; /// <summary>
/// 图片类型
/// </summary>
public ImageTreeControlImageType Type
{
get
{
return _Type;
}
set
{
_Type = value;
PropertyChanged?.Notify(() => this.Type);
}
} /// <summary>
/// 是否选中
/// </summary>
public bool IsSelected
{
get
{
return _IsSelected;
}
set
{
_IsSelected = value;
PropertyChanged?.Notify(() => this.IsSelected);
}
}
} /// <summary>
/// 图片树状,子项类型
/// </summary>
public enum ImageTreeControlItemType
{
/// <summary>
/// 分类
/// </summary>
Classify = ,
/// <summary>
/// 图片资源
/// </summary>
Images =
} /// <summary>
/// 图片树状,所属子项的图片的类型
/// </summary>
public enum ImageTreeControlImageType
{
/// <summary>
/// 什么也不是
/// </summary>
None = -,
/// <summary>
/// 默认
/// </summary>
Default = ,
/// <summary>
/// 抠图
/// </summary>
Matting = ,
/// <summary>
/// 已经对此抠图了
/// </summary>
AlreadyMatting =
}
}

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

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media.Imaging; namespace iPIS.UI.Base.Model
{
/// <summary>
/// 图片树状,子项实体
/// </summary>
public class ImageTreeControlItemModel
{
/// <summary>
/// 唯一标示符
/// </summary>
public string Id { get; set; } /// <summary>
/// 显示名称
/// </summary>
public string Text { get; set; } /// <summary>
/// 绑定值
/// </summary>
public object Value { get; set; } /// <summary>
/// 当前的下级
/// </summary>
public List<ImageTreeControlItemModel> Children { get; set; } /// <summary>
/// 当前节点下的图片集合
/// </summary>
public List<ImageTreeControlImageModel> Images { get; set; } /// <summary>
/// 类别显示图标
/// </summary>
public BitmapImage IconSource { get; set; } = null;
}
}

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

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

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

附上关键代码

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

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

附上关键代码

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

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

附上关键代码

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

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

附上关键代码

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

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

附上关键代码

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

  1. Delphi Treeview 用法(概念、属性、添加编辑插入节点、定位节点、拖拽等)

    今天再细研究了一下Treeview的用法,网上虽然总结了很多,但是还是有很多节点没有讲到了,也给使用中遇到很多问题.特地总结一下: 1.概念 Treeview用于显示按照树形结构进行组织的数据.Tre ...

  2. [转]ms sql 2000 下批量 附加/分离 数据库(sql语句)

    这次公司要把MS SQL Server 2000 服务器上的数据库复制到新的服务器上面去,于是几百个数据库文件就交给我附加到新服务器上了   以前一直没接触过这方面的东西,于是果断谷歌了也百度了  找 ...

  3. Linux下批量修改文件名(rename)

    原文地址: http://blog.csdn.net/sea_shore/article/details/6102437 1.rename命令批量修改文件名, 其实linux下可以使用别的办法来批量修 ...

  4. 转:zTree树控件key配置之title:zTree树节点名称过长如何省略显示且鼠标移入节点上能够显示全称

    当树节点的名称有些很长时,全部显示出来显得很拥挤的情况下,我们会想到用省略节点名称来代替,当鼠标移入节点时能够显示该节点的全称.这样我们应该如何做呢? 首先,我们要在树的节点内多增加一个属性用于设置该 ...

  5. RedisCluster linux下批量删除 key

    Redis Cluster linux下批量删除键 说明 使用时不支持传入参数 , 如 redis_batch_del.sh , 因为在linux下 会自动将 * 解析为当前目录下所有文件名, 目前还 ...

  6. 完美解决,浏览器下拉显示网址问题 | 完美解决,使用原生 scroll 写下拉刷新

    在 web 开发过程中我们经常遇到,不想让用户下拉看到我的地址,也有时候在 div 中没有惯性滚动,就此也出了 iScroll 这种关于滚动条的框架,但是就为了一个体验去使用一个框架好像又不值得,今天 ...

  7. JFreechart在linux下不显示及中文乱码问题

    一.使用JFreeChart建的报表,在window下能正常显示,但是放到linux下就报错,而且有时候会把tomcat挂掉, 原因是jfreechart的在linux系统中需要访问java awt库 ...

  8. css 图片内容在不同分辨率下居中显示(演示的图片宽度是1920px,当图片宽度大于显示屏的宽度时)

    1.img 图片内容在不同分辨率下居中显示(如果隐藏多余,在img外面套一个div  设定overflow: hidden.div的大小就是img显示区域的大小) <!DOCTYPE html& ...

  9. shell下批量重命名svn文件的方法

    shell下批量重命名svn文件的方法 目标: 将svn目录下所有文件重命名 , 原文件前缀为 ucc_ , 批量改为 xmd_ 用tree看下当前svn目录 ucc_1.c ucc_1.h ucc_ ...

随机推荐

  1. JavaScript中hasOwnProperty函数

      JavaScript中hasOwnProperty函数方法是返回一个布尔值,指出一个对象是否具有指定名称的属性. 使用方法: object.hasOwnProperty(proName) 其中参数 ...

  2. OneZero_Aphla发布总结以及自己的体会

    Aphla发布正式结束了.清明时节,总要祭奠点什么. 以下是这一周的燃尽图. 可以发现,并没有燃尽.所以OneZero的Aphla发布失败了. 失败原因有至少以下三点: 1.组长分配任务存在隐患,高风 ...

  3. spring自动类型转换========Converter和PropertyEditor

    Spring有两种自动类型转换器,一种是Converter,一种是propertyEditor. 两者的区别:Converter是类型转换成类型,Editor:从string类型转换为其他类型. 从某 ...

  4. Bubble(冒泡排序)————Java

    用Java进行冒泡排序的代码,利用一个flag进行优化算法: import java.util.Scanner; public class Bubble_Sort { private static i ...

  5. 核心一:DI

    1.DI:中文名称:依赖注入 2.英文名称:(Dependency Injection) 3.DI是什么?? 3.1 DI和IoC是一样的 3.2 当一个类(A)中需要依赖另一类(B)对象时,把B赋值 ...

  6. 必看的经典金融书籍推荐zz

    5. 现代企业财务管理,11th詹姆斯.C.范霍恩,经济科学出版社,2002 6. Financial market and corporate strategy,glinbratt, 四.金融计量 ...

  7. Softmax && Cross-entropy Error

    softmax 函数,被称为 归一化指数函数,是sigmoid函数的推广. 它将向量等比压缩到[0, 1]之间,所有元素和为1. 图解: Example: softmax([1, 2, 3, 4, 1 ...

  8. 证明 U and V={0}时 dim(U+V)=dim(U)+dim(V)

    U And V={0} 证明 dim(U+V)=dim(U)+dim(V)设{u1,u2,...,uk} 是U的基,{v1,v2...,vr}是V的基,dim(U)=k ,dim(V)=r dim(U ...

  9. 使用bat批处理文件定时自动备份sqlserver数据库

    一.创建一个sql文件,在里面写入以下代码: USE MasterGOdeclare @str varchar(100)set @str='D:\sqlserver14backup\CDB\'+rep ...

  10. 535 5.7.8 Error: authentication failed: generic failure安装EMOS时SMTP测试报错

    按照官方手册安装EMOS时候,进行到SMTP认证测试的时候报如下错: 535 5.7.8 Error: authentication failed: generic failure 原来是因为之前关闭 ...