WPF實現好看的跑馬燈特效執行個體

來源:互聯網
上載者:User
這篇文章主要為大家詳細介紹了WPF實現簡單的跑馬燈效果,具有一定的參考價值,感興趣的小夥伴們可以參考一下

最近項目上要用到跑馬燈的效果,和網上不太相同的是,網上大部分都是連續的,而我們要求的是不連續的。

也就是是,介面上就展示4項(展示項數可變),如果有7項要展示的話,則不斷的在4個空格裡左跳,當然,銜接上效果不是很好看。

然後,需要支援點擊以後進行移除掉不再顯示的內容。

效果如下:

思路大致如下:

1、最外層用一個ViewBox,為了可以填充調用此控制項的地方,這樣可以方便自動展開

複製代碼 代碼如下:

<Viewbox x:Name="viewbox_main" Height="{Binding Path=ActualHeight}" Width="{Binding Path=ActualWidth}" MouseLeave="grid_main_MouseLeave" MouseMove="grid_main_MouseMove"  HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stretch="Fill"/>

2、定義三個變數,一個是Count值,是為了設定要展示的UserControl的個數的,例如預設是4個,如,當然,設定成5的話,就是5個了;一個List<Grid>是為了放入展示控制項的列表,一個List<UserControl>是用來放所有要用於跑馬燈裡的控制項的。

3、設定一個Canvas,放入到最外層的Viewbox中,用於跑馬燈時候用(這也是常用的跑馬燈控制項Canvas)

//給Canvas設定一些屬性 canvas_board.VerticalAlignment = VerticalAlignment.Stretch; canvas_board.HorizontalAlignment = HorizontalAlignment.Stretch;canvas_board.Width = this.viewbox_main.ActualWidth;canvas_board.Height = this.viewbox_main.ActualHeight;canvas_board.ClipToBounds = true;//用viewbox可以支援展開this.viewbox_main.Child = canvas_board;

4、將要迴圈的Grid放入到Canvas裡,這裡的Grid的個數,要比展示的個數大一個,也就是Count+1個值,因為滾動的時候,其實是在最外面有一個的,這樣保證了迴圈的走動。至於兩個控制項之間的Margin這個就是要設定Grid的了,到時候控制項是直接扔進Grid裡的


//迴圈將Grid加入到要展示的列表裡for (int i = 0; i < Uc_Count + 1; i++){ Grid grid = new Grid(); grid.Width = canvas_board.Width / Uc_Count - 10; grid.Height = canvas_board.Height - 10; grid.Margin = new Thickness(5); this.canvas_board.Children.Add(grid); grid.SetValue(Canvas.TopProperty, 0.0); grid.SetValue(Canvas.LeftProperty, i * (grid.Width + 10)); UcListForShow.Add(grid);}

5、給每個Grid增加一個動畫效果,就是向左移動的效果


for (int i = 0; i < UcListForShow.Count; i++){ //設定滾動時候的效果 DoubleAnimationUsingKeyFrames daukf_uc = new DoubleAnimationUsingKeyFrames(); LinearDoubleKeyFrame k1_uc = new LinearDoubleKeyFrame(i * (UcListForShow[i].Width + 10), KeyTime.FromTimeSpan(TimeSpan.FromSeconds(2))); LinearDoubleKeyFrame k2_uc = new LinearDoubleKeyFrame((i - 1) * (UcListForShow[i].Width + 10), KeyTime.FromTimeSpan(TimeSpan.FromSeconds(2.5))); daukf_uc.KeyFrames.Add(k1_uc); daukf_uc.KeyFrames.Add(k2_uc); storyboard_imgs.Children.Add(daukf_uc); Storyboard.SetTarget(daukf_uc, UcListForShow[i]); Storyboard.SetTargetProperty(daukf_uc, new PropertyPath("(Canvas.Left)"));}

6、滾動的時候,要計算UserControl到底是添加到了哪個Grid裡面,也就是哪個控制項作為了第一位。

我們設定一個索引值scroll_index,預設的時候,scroll_index=0,這是初始的狀態,當滾動起來以後,scroll_index = scroll_index + 1 - Uc_Count;

然後,判斷,迴圈的時候,是否是展示列表的末尾了,如果是的話,則要填充的控制項是scroll_index %UcListSum.Count(滾動索引,對總數直接取餘數),如果不是的話則是scroll_index++ % UcListSum.Count(滾動索引++,對總數直接取餘數)


scroll_index = scroll_index + 1 - Uc_Count;for (int i = 0; i < UcListForShow.Count; i++){ UcListForShow[i].SetValue(Canvas.LeftProperty, i * (UcListForShow[i].Width + 10)); UserControl uc; if (i == UcListForShow.Count - 1) {  uc = UcListSum[scroll_index % UcListSum.Count]; } else {  uc = UcListSum[scroll_index++ % UcListSum.Count]; } if (uc.Parent != null) {  (uc.Parent as Grid).Children.Clear();//將Usercontrol從原來的裡面移除掉,要不然會拋錯,Usercontrol已屬於另一個控制項 } UcListForShow[i].Children.Clear(); UcListForShow[i].Children.Add(uc); //將隱藏按鈕加入到Grid裡 Button btn = new Button(); btn.Style = (dictionary["hidenStyle"] as Style);//從樣式檔案裡讀取到Button的樣式 btn.Tag = UcListForShow[i].Children;//給Tag賦值,這樣方便尋找 btn.Click += Btn_Click;//註冊隱藏事件 UcListForShow[i].Children.Add(btn);}

代碼中,需要注意的是(uc.Parent as Grid).Children.Clear(),如果不移除的話,則會提示,已經屬於另一個,所以,要從parent裡面移除掉。

7、Button的隱藏事件,當Button點擊以後,則要進行隱藏,其實也就是將總數裡面,減除掉不再顯示的那一項


private void Btn_Click(object sender, RoutedEventArgs e){ if ((sender as Button).Tag != null) {  UcListSum.Remove((((sender as Button).Tag as UIElementCollection)[0] as UserControl)); } if (UcListSum.Count == Uc_Count)//當列表數和要展示的數目相同的時候,就停止掉動畫效果 {  storyboard_imgs.Completed -= Storyboard_imgs_Completed;  storyboard_imgs.Stop();  for (int i = 0; i < Uc_Count; i++)  {   UcListForShow[i].Children.Clear();   if (UcListSum[i].Parent != null)   {    (UcListSum[i].Parent as Grid).Children.Clear();   }   UcListForShow[i].Children.Add(UcListSum[i]);  }  return; }}

所有代碼如下:


using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Documents;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Animation;using System.Windows.Media.Imaging;using System.Windows.Navigation;using System.Windows.Shapes;namespace MarqueeUserControl{ /// <summary> /// MarqueeUC.xaml 的互動邏輯 /// </summary> public partial class MarqueeUC : UserControl {  ResourceDictionary dictionary;  public MarqueeUC()  {   InitializeComponent();   //讀取樣式檔案   dictionary = new ResourceDictionary { Source = new Uri("/MarqueeUserControl;component/MarqueeUserControlDictionary.xaml", UriKind.Relative) };  }  #region 屬性  private int _uc_Count = 0;  /// <summary>  /// 用來展示幾個  /// </summary>  public int Uc_Count  {   get   {    return _uc_Count;   }   set   {    _uc_Count = value;   }  }  private List<Grid> _ucListForShow = new List<Grid>();  /// <summary>  /// 用來展示的控制項列表  /// </summary>  private List<Grid> UcListForShow  {   get   {    return _ucListForShow;   }   set   {    _ucListForShow = value;   }  }  private List<UserControl> _ucListSum = new List<UserControl>();  /// <summary>  /// 要添加的控制項的列表  /// </summary>  public List<UserControl> UcListSum  {   get   {    return _ucListSum;   }   set   {    _ucListSum = value;   }  }  #endregion  Canvas canvas_board = new Canvas();  Storyboard storyboard_imgs = new Storyboard();  int scroll_index = 0;//滾動索引  double scroll_width;//滾動寬度  void GridLayout()  {   if (Uc_Count == 0)//如果這個值沒有賦值的話,則預設顯示四個   {    Uc_Count = 4;   }   //給Canvas設定一些屬性   canvas_board.VerticalAlignment = VerticalAlignment.Stretch;   canvas_board.HorizontalAlignment = HorizontalAlignment.Stretch;   canvas_board.Width = this.viewbox_main.ActualWidth;   canvas_board.Height = this.viewbox_main.ActualHeight;   canvas_board.ClipToBounds = true;   //用viewbox可以支援展開   this.viewbox_main.Child = canvas_board;   //迴圈將Grid加入到要展示的列表裡   for (int i = 0; i < Uc_Count + 1; i++)   {    Grid grid = new Grid();    grid.Width = canvas_board.Width / Uc_Count - 10;    grid.Height = canvas_board.Height - 10;    grid.Margin = new Thickness(5);    this.canvas_board.Children.Add(grid);    grid.SetValue(Canvas.TopProperty, 0.0);    grid.SetValue(Canvas.LeftProperty, i * (grid.Width + 10));    UcListForShow.Add(grid);   }  }  void StoryLoad()  {   for (int i = 0; i < UcListForShow.Count; i++)   {//設定滾動時候的效果    DoubleAnimationUsingKeyFrames daukf_uc = new DoubleAnimationUsingKeyFrames();    LinearDoubleKeyFrame k1_uc = new LinearDoubleKeyFrame(i * (UcListForShow[i].Width + 10), KeyTime.FromTimeSpan(TimeSpan.FromSeconds(2)));    LinearDoubleKeyFrame k2_uc = new LinearDoubleKeyFrame((i - 1) * (UcListForShow[i].Width + 10), KeyTime.FromTimeSpan(TimeSpan.FromSeconds(2.5)));    daukf_uc.KeyFrames.Add(k1_uc);    daukf_uc.KeyFrames.Add(k2_uc);    storyboard_imgs.Children.Add(daukf_uc);    Storyboard.SetTarget(daukf_uc, UcListForShow[i]);    Storyboard.SetTargetProperty(daukf_uc, new PropertyPath("(Canvas.Left)"));   }   storyboard_imgs.FillBehavior = FillBehavior.Stop;   storyboard_imgs.Completed += Storyboard_imgs_Completed;   storyboard_imgs.Begin();  }  private void Storyboard_imgs_Completed(object sender, EventArgs e)  {   scroll_index = scroll_index + 1 - Uc_Count;   for (int i = 0; i < UcListForShow.Count; i++)   {    UcListForShow[i].SetValue(Canvas.LeftProperty, i * (UcListForShow[i].Width + 10));    UserControl uc;    if (i == UcListForShow.Count - 1)    {     uc = UcListSum[scroll_index % UcListSum.Count];    }    else    {     uc = UcListSum[scroll_index++ % UcListSum.Count];    }    if (uc.Parent != null)    {     (uc.Parent as Grid).Children.Clear();//將Usercontrol從原來的裡面移除掉,要不然會拋錯,Usercontrol已屬於另一個控制項    }    UcListForShow[i].Children.Clear();    UcListForShow[i].Children.Add(uc);    //將隱藏按鈕加入到Grid裡    Button btn = new Button();    btn.Style = (dictionary["hidenStyle"] as Style);//從樣式檔案裡讀取到Button的樣式    btn.Tag = UcListForShow[i].Children;//給Tag賦值,這樣方便尋找    btn.Click += Btn_Click;//註冊隱藏事件    UcListForShow[i].Children.Add(btn);   }   storyboard_imgs.Begin();  }  private void Btn_Click(object sender, RoutedEventArgs e)  {   if ((sender as Button).Tag != null)   {    UcListSum.Remove((((sender as Button).Tag as UIElementCollection)[0] as UserControl));   }   if (UcListSum.Count == Uc_Count)//當列表數和要展示的數目相同的時候,就停止掉動畫效果   {    storyboard_imgs.Completed -= Storyboard_imgs_Completed;    storyboard_imgs.Stop();    for (int i = 0; i < Uc_Count; i++)    {     UcListForShow[i].Children.Clear();     if (UcListSum[i].Parent != null)     {      (UcListSum[i].Parent as Grid).Children.Clear();     }     UcListForShow[i].Children.Add(UcListSum[i]);    }    return;   }  }  public void StartMar()  {   GridLayout();   scroll_width = this.canvas_board.Width;   for (int i = 0; i < UcListForShow.Count; i++)   {    UserControl uc;    if (i == UcListForShow.Count - 1)    {     uc = UcListSum[scroll_index % UcListSum.Count];    }    else    {     uc = UcListSum[scroll_index++ % UcListSum.Count];    }    if (uc.Parent != null)    {     (uc.Parent as Grid).Children.Clear();    }    UcListForShow[i].Children.Clear();    UcListForShow[i].Children.Add(uc);   }   StoryLoad();  }  private void grid_main_MouseLeave(object sender, MouseEventArgs e)  {   if (storyboard_imgs.GetCurrentState() == ClockState.Stopped)//如果是停止的狀態,則直接返回,不再起作用   {    return;   }   if (storyboard_imgs.GetIsPaused() == true)//如果是暫停狀態的話,則開始   {    storyboard_imgs.Begin();   }  }  private void grid_main_MouseMove(object sender, MouseEventArgs e)  {   if (storyboard_imgs.GetIsPaused() == false)   {    storyboard_imgs.Pause();   }  } }}


<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"     xmlns:local="clr-namespace:MarqueeUserControl"> <Style TargetType="Button" x:Key="hidenStyle">  <Setter Property="Background" Value="Transparent"/>  <Setter Property="HorizontalAlignment" Value="Center"/>  <Setter Property="VerticalAlignment" Value="Center"/>  <Setter Property="Width" Value="25"/>  <Setter Property="Height" Value="25"/>  <Setter Property="BorderBrush" Value="Transparent"/>  <Setter Property="BorderThickness" Value="0"/>  <Setter Property="Template"><!--把Image放到Template裡作為Content顯示,如果是單獨給Content設定圖片的話,則只有一個按鈕顯示圖片,其他的不顯示-->   <Setter.Value>    <ControlTemplate TargetType="{x:Type Button}">     <Border>      <Image Source="hiden.png"/>     </Border>    </ControlTemplate>   </Setter.Value>  </Setter> </Style></ResourceDictionary>

沒有解決的問題

想給Button增加滑鼠移至上方的時候,顯示,移除的時候隱藏,但是發現不好使,原因是當MouseOver上去的時候,雖然Visibility的值變了,但是只有到下一次的時候,Button的值才被附上,而此時,已經MouseLeave了,請哪位大神指導一下,看看這個顯示和隱藏怎麼做。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.