zoukankan      html  css  js  c++  java
  • WPF 应用

    1. 功能

    • 做一个图片集合控件,在指定大小的区域内,以走马灯的动画效果呈现图片。
    • 能根据图片的数量决定动画的方向。当图片集合的大小大于指定的大小,图片往反方向走,以便于能看到底部的图片;当图片集合的大小小于指定的大小时,图片往正方向走,以便于保证所有图片都一直在可视区域内。
    • 根据图片的数量,决定动画的时间,保持速度不变。

    2. 效果

    3. 代码

    3.1 内部动画流动控件 FlowImagesUserControl
    <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();
        }
    }
    
    3.2 在窗口中添加 FlowImagesUserControl 控件
    <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
                });
            }
        }
    }
    
    3.3 鼠标移入图片效果

    鼠标移入图片时,动画会停止。这里再给图片添加一个鼠标移入效果,当鼠标移入时,图片变大,鼠标移出后,图片恢复大小。

    <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>
    

  • 相关阅读:
    android学习笔记----启动模式与任务栈(Task)
    二叉搜索树转化成双向链表
    复杂链表的复制
    判断是否为二叉搜索树的后序遍历序列
    树的子结构
    调整数组顺序使奇数位于偶数前面,且奇数之间、偶数之间的相对位置不变
    android学习笔记----HandlerThread学习
    android学习笔记----Handler的使用、内存泄漏、源码分析等一系列问题
    原因分析——cin,coutTLE,scanf,printf就AC
    洛谷P1618_三连击(升级版)
  • 原文地址:https://www.cnblogs.com/MichaelLoveSna/p/14494245.html
Copyright © 2011-2022 走看看