1. 程式人生 > >WPF使用Storyboard實現圖片跑馬燈效果

WPF使用Storyboard實現圖片跑馬燈效果

新建一個wpf專案,新增演示用圖片,修改圖片屬性為"如果較新則複製"。(這裡要注意,一定要修改屬性!)

在MainWindow.xaml中,為系統自動建立的Grid容器命名,這樣可以在後臺操作的到它。

<Window x:Class="WpfRollPic.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="
350" Width="525" Loaded="Window_Loaded"> <Grid Name="grid_main"></Grid> </Window>

在後臺程式碼中,新增窗體佈局。

 public MainWindow()
        {
            InitializeComponent();
            this.GridLayout();
        }

        Canvas canvas_board = new Canvas();
        Image image1 = new
Image(); Image image2 = new Image(); void GridLayout() { this.WindowStartupLocation = WindowStartupLocation.CenterScreen; this.Width = 300; this.Height = 300; canvas_board.VerticalAlignment = VerticalAlignment.Top; canvas_board.HorizontalAlignment = HorizontalAlignment.Left; canvas_board.Margin = new
Thickness(10, 10, 0, 0); canvas_board.Width = 200; canvas_board.Height = 200; //canvas_board.Background = new SolidColorBrush(Colors.LightBlue); canvas_board.ClipToBounds = true; this.grid_main.Children.Add(canvas_board); image1.Stretch = Stretch.Fill; image1.Width = 200; image1.Height = 200; this.canvas_board.Children.Add(image1); image1.SetValue(Canvas.TopProperty, 0.0); image1.SetValue(Canvas.LeftProperty, 0.0); image2.Stretch = Stretch.Fill; image2.Width = 200; image2.Height = 200; this.canvas_board.Children.Add(image2); image2.SetValue(Canvas.TopProperty, 200.0); image2.SetValue(Canvas.LeftProperty, 0.0); }

注意這裡需要設定Canvas控制元件的ClipToBounds屬性為true,這樣Canvas將不再顯示出超出自己範圍以外的內容。同時使用到了SetValue方法來設定Image控制元件的Canvas.Top/Canvas.Left屬性。

新增初始化函式,程式碼如下:

        List<BitmapImage> ls_images = new List<BitmapImage>(); //存放圖片組        int n_index = 0;    //滾動索引        double n_height;   //滾動高度
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            string[] img_files = Directory.GetFiles(string.Format("{0}../../Images", AppDomain.CurrentDomain.SetupInformation.ApplicationBase), "*.png");
            foreach (string img_path in img_files)
            {
                ls_images.Add(new BitmapImage(new Uri(img_path, UriKind.Absolute)));
            }
            n_height = this.canvas_board.Height;
            this.image1.Source = ls_images[n_index++ % ls_images.Count];
            this.image2.Source = ls_images[n_index % ls_images.Count];

            this.StoryLoad();
        }

這裡完成了一些圖片素材的初始化,下面還需要完成故事板StoryLoad初始化事件:

        Storyboard storyboard_imgs = new Storyboard();

        void StoryLoad()
        {
            DoubleAnimationUsingKeyFrames daukf_img1 = new DoubleAnimationUsingKeyFrames();
            LinearDoubleKeyFrame k1_img1 = new LinearDoubleKeyFrame(0.0, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(2)));
            LinearDoubleKeyFrame k2_img1 = new LinearDoubleKeyFrame(-n_height, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(4)));
            daukf_img1.KeyFrames.Add(k1_img1);
            daukf_img1.KeyFrames.Add(k2_img1);
            storyboard_imgs.Children.Add(daukf_img1);
            Storyboard.SetTarget(daukf_img1, image1);
            Storyboard.SetTargetProperty(daukf_img1, new PropertyPath("(Canvas.Top)"));

            DoubleAnimationUsingKeyFrames daukf_img2 = new DoubleAnimationUsingKeyFrames();
            LinearDoubleKeyFrame k1_img2 = new LinearDoubleKeyFrame(n_height, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(2)));
            LinearDoubleKeyFrame k2_img2 = new LinearDoubleKeyFrame(0.0, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(4)));
            daukf_img2.KeyFrames.Add(k1_img2);
            daukf_img2.KeyFrames.Add(k2_img2);
            storyboard_imgs.Children.Add(daukf_img2);
            Storyboard.SetTarget(daukf_img2, image2);
            Storyboard.SetTargetProperty(daukf_img2, new PropertyPath("(Canvas.Top)"));

            storyboard_imgs.FillBehavior = FillBehavior.Stop;
            storyboard_imgs.Completed += new EventHandler(storyboard_imgs_Completed);
            storyboard_imgs.Begin();
        }

注意到添加了關鍵幀,

關鍵幀1:實現跑馬燈圖片停頓的效果,可以按照需求設定關鍵幀的時長就是停頓的時長;

關鍵幀2:實現跑馬燈的滾動效果,可以設定關鍵幀的時長就是滾動一次所需時間;

注意到這裡必須設定故事板storyboard_imgs的FillBehavior屬性為Stop,這樣在一個故事結束後,所有與故事相關聯的屬性將可以回到初始狀態。

下面完成故事板storyboard_imgs的完成Completed事件,程式碼如下:

        void storyboard_imgs_Completed(object sender, EventArgs e)
        {
            image1.SetValue(Canvas.TopProperty, 0.0);
            image2.SetValue(Canvas.TopProperty, n_height);
            image1.Source = ls_images[n_index++ % ls_images.Count];
            image2.Source = ls_images[n_index % ls_images.Count];
            storyboard_imgs.Begin();
        }

Completed事件中,更改了image1和image2的圖片,這樣看起來,改變圖片和位置的image1就好像變成了之前的image2,從而達到跑馬燈的效果。

 重新生成專案,F5執行,效果如下: