本次案例主要使用了HC
中的 WaterfallPanel
、Drawer
、SimplePanel
。
实际效果如下:
一、准备工作
使用 HC
开始的第一步是,WPF
项目引入库依赖,然后 App.xaml
引入全局资源字典。
<Application x:Class="WPFImageExplorer.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="MainWindow.xaml"> <Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/SkinDefault.xaml"/> <ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Theme.xaml"/> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources> </Application>
二、控件样式
1、绑定代理类 BindingProxy
public class BindingProxy : Freezable { protected override Freezable CreateInstanceCore() { return new BindingProxy(); } public object Data { get { return (object)GetValue(DataProperty); } set { SetValue(DataProperty, value); } } public static readonly DependencyProperty DataProperty = DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null)); }
2、父级资源
<local:BindingProxy x:Key="ImageLst" Data="{Binding ElementName=ImageLst, Mode=OneWay}"></local:BindingProxy> <Style x:Key="ListBoxItem.Common" TargetType="{x:Type ListBoxItem}"> <Setter Property="Cursor" Value="Hand"/> <Setter Property="FocusVisualStyle" Value="{x:Null}"/> <Setter Property="VerticalAlignment" Value="Stretch"/> <Setter Property="HorizontalAlignment" Value="Stretch"/> </Style> <Style x:Key="ListBox.Large" BasedOn="{StaticResource ListBoxCustom}" TargetType="{x:Type ListBox}"> <Setter Property="VerticalContentAlignment" Value="Center"/> <Setter Property="ItemContainerStyle" Value="{StaticResource ListBoxItem.Common}"/> <Setter Property="ItemsPanel"> <Setter.Value> <ItemsPanelTemplate> <hc:WaterfallPanel AutoGroup="True" DesiredLength="210" ></hc:WaterfallPanel> </ItemsPanelTemplate> </Setter.Value> </Setter> <Setter Property="ItemTemplate"> <Setter.Value> <DataTemplate DataType="{x:Type vm:ImageObject}"> <Border Padding="0,4" MinWidth="210" MinHeight="210"> <DockPanel x:Name="Content" MaxWidth="210" MaxHeight="210"> <TextBlock TextBlock.TextAlignment="Center" TextWrapping="Wrap" Text="{Binding Name}" DockPanel.Dock="Bottom"></TextBlock> <Image Stretch="Uniform" Margin="0,4" ToolTip="{Binding Name}" VerticalAlignment="Bottom" Source="{Binding Path}"> <Image.Effect> <DropShadowEffect ShadowDepth="2" BlurRadius="10" Direction="270" Color="Black" Opacity="0.4"></DropShadowEffect> </Image.Effect> </Image> </DockPanel> </Border> </DataTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="ListBox.Normal" BasedOn="{StaticResource ListBoxCustom}" TargetType="{x:Type ListBox}"> <Setter Property="VerticalContentAlignment" Value="Center"/> <Setter Property="HorizontalContentAlignment" Value="Left"/> <Setter Property="ItemContainerStyle" Value="{StaticResource ListBoxItem.Common}"/> <Setter Property="ItemsPanel"> <Setter.Value> <ItemsPanelTemplate> <hc:WaterfallPanel AutoGroup="True" DesiredLength="210" ></hc:WaterfallPanel> </ItemsPanelTemplate> </Setter.Value> </Setter> <Setter Property="ItemTemplate"> <Setter.Value> <DataTemplate DataType="{x:Type vm:ImageObject}"> <DockPanel ToolTip="{Binding Name}" MinWidth="210" MinHeight="210"> <TextBlock TextBlock.TextAlignment="Center" TextWrapping="Wrap" VerticalAlignment="Center" Text="{Binding Name}" DockPanel.Dock="Right"></TextBlock> <Image Stretch="Uniform" Margin="5" Width="100" Height="100" HorizontalAlignment="Left" VerticalAlignment="Center" Source="{Binding Path}"> </Image> </DockPanel> </DataTemplate> </Setter.Value> </Setter> </Style>
3、控件布局
<DockPanel> <hc:Drawer Name="DrawerLeft" Dock="Right" ShowMode="Cover"> <hc:SimplePanel> <Border BorderThickness="0" BorderBrush="Transparent" Background="{DynamicResource RegionBrush}" Width="{Binding Data.ActualWidth, Source={StaticResource ImageLst}}"> <hc:ImageViewer Name="ImageViewer"></hc:ImageViewer> </Border> <Button Cursor="Hand" Command="hc:ControlCommands.Close" HorizontalAlignment="Left" VerticalAlignment="Top" Foreground="{DynamicResource PrimaryTextBrush}" Opacity="0.5" Style="{DynamicResource ButtonIcon}" hc:IconElement.Geometry="{DynamicResource DeleteFillCircleGeometry}"/> </hc:SimplePanel> </hc:Drawer> <StackPanel DockPanel.Dock="Top" Orientation="Horizontal" HorizontalAlignment="Center"> <Button x:Name="btn_selected" Content="加载" Click="btn_selected_Click"></Button> <hc:ButtonGroup Style="{DynamicResource ButtonGroupSolid}"> <RadioButton Style="{StaticResource ToggleButtonIcon}" hc:IconElement.Geometry="{DynamicResource AllGeometry}" Tag="Normal" x:Name="btn_nomal" Checked="btn_nomal_Checked"></RadioButton> <RadioButton Style="{StaticResource ToggleButtonIcon}" hc:IconElement.Geometry="{DynamicResource FatalGeometry}" Tag="Large" x:Name="btn_large" Checked="btn_nomal_Checked"></RadioButton> </hc:ButtonGroup> </StackPanel> <ListBox x:Name="ImageLst" Padding="0" MinWidth="210" Style="{StaticResource ListBox.Normal}" SelectionChanged="ImageLst_Selected" d:ItemsSource="{d:SampleData ItemCount=5}"> </ListBox> </DockPanel>
三、数据实体
1、数据实体
public class ImageObject { public ImageObject(FileInfo file) { Name = file.Name; Path = file.FullName; ModifyDate = file.LastWriteTime; } public string Name { get; set; } public string Path { get; set; } public DateTime ModifyDate { get; set; } } public class ImageCollection : Collection<ImageObject> {
2、加载数据
string folder = @"图片物理路径"; DateTime startdate = DateTime.Parse("2015/01/01"); DateTime enddate = DateTime.Parse("2022/02/01"); System.IO.FileInfo[] files = new System.IO.DirectoryInfo(folder).GetFiles("*.jpg").Where(x => x.LastWriteTime >= startdate && x.LastWriteTime <= enddate).OrderBy(x => x.LastWriteTime).Take(100).ToArray(); int count = files.Length; ImageCollection images = new ImageCollection(); for (int i = 0; i < count; i++) { images.Add(new ImageObject(files[i])); } ImageLst.ItemsSource = images;
3、样式切换
RadioButton radioButton = sender as RadioButton; if (radioButton != null) { string tag = radioButton.Tag?.ToString(); if (string.IsNullOrEmpty(tag)) { return; } string strkey = $"ListBox.{tag}"; var keystyle = FindResource(strkey) as Style; if (keystyle != null) { ImageLst.Style = keystyle; } }