This article is mainly for you to introduce the WPF implementation of a simple marquee effect, with a certain reference value, interested in small partners can refer to
Recent projects to use the effect of the marquee, and the internet is not the same, most of the online is continuous, and we are asking for a discontinuous.
That is, the interface on the display of 4 items (the number of display items variable), if there are 7 to show, then constantly in 4 spaces to jump to the left, of course, the effect is not very good cohesion.
Then, you need to support clicking to remove content that is no longer displayed.
The effect is as follows:
The idea is roughly as follows:
1, the outermost layer with a viewbox, in order to be able to fill the place to call this control, so that it is easy to automatically stretch
Copy the Code code as follows:
<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, define three variables, one is the count value, is to set the number of UserControl to show, for example, the default is 4, such as, of course, set to 5, is 5; a list<grid> is to put a list of display controls <UserControl> is used to put all the controls that are used in the marquee.
3, set a canvas, put into the outermost viewbox, used for the marquee (this is also a popular marquee control canvas)
Set some property canvas_board for the canvas. 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;//with Viewbox can support stretching this.viewbox_main. Child = Canvas_board;
4, will loop the grid into the canvas, here the number of grid, than the number of the display of a large, that is, count+1 value, because when scrolling, in fact, in the outermost there is a, so as to ensure the circulation of the walk. As for the margin between two controls this is to set the grid, when the control is thrown directly into the grid
Loops Add the grid to the list to be displayed 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. Add an animation effect to each grid, which is the effect of moving to the left
for (int i = 0; i < Uclistforshow.count; i++) {//Set scrolling effect doubleanimationusingkeyframes DAUKF_UC = new DoubleAnimation Usingkeyframes (); LinearDoubleKeyFrame K1_uc = new LinearDoubleKeyFrame (i * (Uclistforshow[i]. Width + Ten), Keytime.fromtimespan (Timespan.fromseconds (2))); LinearDoubleKeyFrame K2_uc = new LinearDoubleKeyFrame ((i-1) * (Uclistforshow[i]. Width + Ten), 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, when scrolling, to calculate UserControl in the end is added to which grid inside, that is, which control as the first bit.
We set an index value Scroll_index, by default, Scroll_index=0, which is the initial state when scrolling up, Scroll_index = Scroll_index + 1-uc_count;
Then, judging when the loop, whether it is the end of the display list, if so, the control to be populated is Scroll_index%uclistsum.count (scrolling index, the total number of directly take the remainder), if not, it is scroll_index++% Uclistsum.count (scroll index + +, take the remainder directly to the total)
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 ();//Remove UserControl from the original, otherwise it will be wrong, UserControl already belong to another control} Uclistforshow[i]. Children.clear (); Uclistforshow[i]. Children.add (UC); Add hidden buttons to Grid button BTN = New button (); Btn. style = (dictionary["Hidenstyle"] as style);//reads the style btn from the style file to the button. Tag = Uclistforshow[i]. children;//assigns a value to tag so that it is easy to find BTN. Click + = btn_click;//Register hidden event Uclistforshow[i]. Children.add (BTN);}
In the code, it is important to note that (UC. Parent as Grid). Children.clear (), if not removed, will prompt that it belongs to another, so remove it from the parent.
7, Button of the hidden event, when the button click, you want to hide, in fact, the total number inside, minus the display of the item is no longer
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)//When the number of lists is the same as the number to show, stop the animation { 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 }}
All codes are as follows:
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 Interactive logic///</summary> public partial class Marqueeuc:usercontrol {ResourceDictionary dictionary; Public Marqueeuc () {InitializeComponent (); Read Style file dictionary = new ResourceDictionary {Source = new Uri ("/marqueeusercontrol;component/marqueeusercontroldictio Nary.xaml ", urikind.relative)}; } #region Property private int _uc_count = 0; <summary>///for displaying several//</summary> public int Uc_count {get {return _uc_count; } set {_uc_count = value; }} private List<grid> _uclistforshow = new LiSt<grid> (); <summary>///The list of controls to be displayed///</summary> private list<grid> uclistforshow {get {return _u Clistforshow; } set {_uclistforshow = value; }} private List<usercontrol> _uclistsum = new list<usercontrol> (); <summary>////List of controls to add///</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;//scrolling index double scroll_width;//scroll width void GridLayout () {if (Uc_count = = 0)//If this value is not assigned, four is displayed by default {uc_count = 4; }//Set some property canvas_board for canvas. 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; With VIewbox can support stretching this.viewbox_main. Child = Canvas_board; Loops Add the grid to the list to be displayed 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++) {//sets the effect of scrolling time Doubleanimationusingkeyfram Es daukf_uc = new DoubleAnimationUsingKeyFrames (); LinearDoubleKeyFrame K1_uc = new LinearDoubleKeyFrame (i * (Uclistforshow[i]. Width + Ten), Keytime.fromtimespan (Timespan.fromseconds (2))); LinearDoubleKeyFrame K2_uc = new LinearDoubleKeyFrame ((i-1) * (Uclistforshow[i]. Width + Ten), 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 ();//Remove UserControl from the original, otherwise it will be wrong, UserControl already belong to another control} Uclistforshow[i]. Children.clear (); Uclistforshow[i]. Children.add (UC); Add hidden buttons to Grid button BTN = new ButtOn (); Btn. style = (dictionary["Hidenstyle"] as style);//reads the style btn from the style file to the button. Tag = Uclistforshow[i]. children;//assigns a value to tag so that it is easy to find BTN. Click + = btn_click;//Register hidden event Uclistforshow[i]. Children.add (BTN); } storyboard_imgs. Begin (); The 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)//When the number of lists is the same as the number to show, stop the animation {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 (); The private void Grid_main_mouseleave (object sender, MouseEventArgs e) {if (Storyboard_imgs. Getcurrentstate () = = clockstate.stopped)//If it is a stopped state, then return directly, no longer function {return; } if (Storyboard_imgs. getispaused () = = true)//If it is a paused state, start {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= "/> <setter property=" Height "value=" "/> <setter property=" BorderBrush "Value = "Transparent"/> <setter property= "borderthickness" value= "0"/> <setter property= "Template" ><!-- Put the image in the template as a content display, if you set a picture for content alone, then there is only one button to display the picture, others do not display-<Setter.Value> < ControlTemplate targettype= "{x:type button}" > <Border> <image source= "Hiden.png"/> </border > </ControlTemplate> </Setter.Value> </Setter> </Style></ResourceDictionary>
No problem solved
Want to give the button to increase the mouse hover, display, remove the time hidden, but found not so, because when the mouseover up, although the value of visibility changed, but only to the next time, the value of the button is attached, and at this time, has been mouseleave, please which big God guide, see this show and hide how to do.