<UserControl x:Class="WpfAppTemplate.FlowImagesUserControl" 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:WpfAppTemplate" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800" x:Name="selfUserControl"> <StackPanel Orientation="Horizontal"> <ItemsControl x:Name="itemsControl" ItemsSource="{Binding}" Loaded="itemsControl_Loaded" MouseEnter="itemsControl_MouseEnter" MouseLeave="itemsControl_MouseLeave"> <ItemsControl.RenderTransform> <TransformGroup> <TranslateTransform X="0" Y="0"></TranslateTransform> </TransformGroup> </ItemsControl.RenderTransform> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <StackPanel Orientation="Horizontal"/> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate> <Image Source="{Binding PicPath}" ToolTip="{Binding Name}" x:Name="img" Width="{Binding ImageWidth, ElementName=selfUserControl}"/> </DataTemplate> </ItemsControl.ItemTemplate> <ItemsControl.Resources> <Storyboard x:Key="storyBoard"> <DoubleAnimation Storyboard.TargetName="itemsControl" Storyboard.TargetProperty="(RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.X)" To="{Binding ToX, ElementName=selfUserControl}" Duration="{Binding Duration, ElementName=selfUserControl}" AutoReverse="True" RepeatBehavior="Forever" /> </Storyboard> </ItemsControl.Resources> </ItemsControl> </StackPanel> </UserControl>
public partial class FlowImagesUserControl : UserControl { /// <summary> /// 圖片大小 /// </summary> public double ImageWidth { get { return (double)GetValue(ImageWidthProperty); } set { SetValue(ImageWidthProperty, value); } } public static readonly DependencyProperty ImageWidthProperty = DependencyProperty.Register("ImageWidth", typeof(double), typeof(FlowImagesUserControl), new PropertyMetadata(60.0)); /// <summary> /// 動畫結束值 /// </summary> public double ToX { get { return (double)GetValue(ToXProperty); } set { SetValue(ToXProperty, value); } } public static readonly DependencyProperty ToXProperty = DependencyProperty.Register("ToX", typeof(double), typeof(FlowImagesUserControl), new PropertyMetadata(500.0)); /// <summary> /// 動畫時間 /// </summary> public Duration Duration { get { return (Duration)GetValue(DurationProperty); } set { SetValue(DurationProperty, value); } } public static readonly DependencyProperty DurationProperty = DependencyProperty.Register("Duration", typeof(Duration), typeof(FlowImagesUserControl), new PropertyMetadata(new Duration(new System.TimeSpan(0,0,2)))); private Storyboard _storyboard; public FlowItemsUserControl() { InitializeComponent(); _storyboard = itemsControl.FindResource("storyBoard") as Storyboard; itemsControl.SizeChanged += (s, e) => { if (this.IsLoaded) { InitParamsOfStoryboard(); } }; } private void itemsControl_Loaded(object sender, RoutedEventArgs e) { InitParamsOfStoryboard(); } private void itemsControl_MouseEnter(object sender, MouseEventArgs e) { _storyboard.Pause(); } private void itemsControl_MouseLeave(object sender, MouseEventArgs e) { _storyboard.Resume(); } private void InitParamsOfStoryboard() { _storyboard.Stop(); // 當集合的大小發生改變時,根據集合的大小決定動畫的位移 ToX = this.ActualWidth - itemsControl.ActualWidth; // 根據位移來決定動畫的總時間,以每秒走 25px 的速度,避免不一樣位移相同時間致使速度不可控 Duration = new Duration(new System.TimeSpan(0, 0, System.Math.Abs((int)ToX/25))); _storyboard.Begin(); } }
<local:FlowItemsUserControl DataContext="{Binding Cars}" ImageWidth="100"/> <Button Grid.Row="1" Content="刪除一輛車" Click="Button_Click" Width="100" Background="DarkSalmon"/>
public partial class ContentWindow : Window { public ContentWindow() { InitializeComponent(); this.DataContext = new CarsViewModel(); } private void Button_Click_DeleteACar(object sender, RoutedEventArgs e) { var carList = (this.DataContext as CarsViewModel).Cars; if (carList != null && carList.Count > 0) { carList.RemoveAt(carList.Count - 1); } } }
public class Car { public string Name { get; set; } public string PicPath { get; set; } } public class NotifyPropertyChanged : System.ComponentModel.INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public void OnProperty(string propertyName) { PropertyChangedEventHandler propertyChanged = PropertyChanged; if (propertyChanged != null) { propertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } } public class CarsViewModel : NotifyPropertyChanged { private ObservableCollection<Car> _Cars; public ObservableCollection<Car> Cars { get { return _Cars; } set { _Cars = value; OnProperty("Cars"); } } public CarsViewModel() { InitCars(); } private void InitCars() { string path = AppDomain.CurrentDomain.BaseDirectory + "/Resources/Images/Cars"; if (!Directory.Exists(path)) { return; } Cars = new ObservableCollection<Car>(); // 獲取文件夾下的全部車輛圖片 FileInfo[] fileArr = new DirectoryInfo(path).GetFiles(); for (int i = 0, l = fileArr.Count(); i < l; i++) { Cars.Add(new Car() { PicPath = fileArr[i].FullName, Name = fileArr[i].Name.Split('.')[0] //fileArr[i].Name = 寶馬.jpg }); } } }
鼠標移入圖片時,動畫會中止。這裏再給圖片添加一個鼠標移入效果,當鼠標移入時,圖片變大,鼠標移出後,圖片恢復大小。express
<Style TargetType="Image" x:Key="MoveInBiggerImageStyle"> <Setter Property="RenderTransform"> <Setter.Value> <TransformGroup> <ScaleTransform/> </TransformGroup> </Setter.Value> </Setter> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Cursor" Value="Hand"/> <Trigger.EnterActions> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetProperty="(RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" To="1.1" Duration="0:0:0.2"/> <DoubleAnimation Storyboard.TargetProperty="(RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" To="1.1" Duration="0:0:0.2"/> </Storyboard> </BeginStoryboard> </Trigger.EnterActions> <Trigger.ExitActions> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetProperty="(RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" To="1" Duration="0:0:0.5"/> <DoubleAnimation Storyboard.TargetProperty="(RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" To="1" Duration="0:0:0.5"/> </Storyboard> </BeginStoryboard> </Trigger.ExitActions> </Trigger> </Style.Triggers> </Style> ... <Image x:Name="img" Source="{Binding PicPath}" ToolTip="{Binding Name}" Width="{Binding ImageWidth, ElementName=selfUserControl}" Style="{StaticResource MoveInBiggerImageStyle}"> </Image>