本次案例主要使用了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;
}
}