In diesem Artikel wird hauptsächlich die Implementierung des einfachen Marquee-Effekts im Detail vorgestellt, der einen gewissen Referenzwert hat.
Der Marquee-Effekt unterscheidet sich von dem im Internet Der größte Teil des Internets ist kontinuierlich, aber was wir benötigen, ist diskontinuierlich.
Das heißt, es werden 4 Elemente auf der Benutzeroberfläche angezeigt (die Anzahl der angezeigten Elemente ist variabel). Wenn 7 Elemente angezeigt werden sollen, springen Sie natürlich weiterhin nach links Verbindungseffekt ist nicht sehr gut.
Dann müssen Sie das Klicken unterstützen, um Inhalte zu entfernen, die nicht mehr angezeigt werden.
Der Effekt ist wie folgt:
Die Idee ist ungefähr wie folgt:
1 Verwenden Sie eine ViewBox in der äußersten Ebene Um das Steuerelement auszufüllen, das es aufruft, kann dies das automatische Dehnen erleichtern.
Code kopieren Der Code lautet wie folgt:
<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"/>
Definieren Sie drei Eine davon ist der Count-Wert, der zum Festlegen der Anzahl der anzuzeigenden UserControls dient. Der Standardwert ist beispielsweise 4, wie im Rendering gezeigt. Wenn er auf 5 eingestellt ist, ist er natürlich 5 List
3. Richten Sie eine Leinwand ein und platzieren Sie sie in der äußersten Ansichtsbox zur Verwendung während der Laufschrift (dies ist auch eine häufig verwendete Laufschrift-Steuerungsleinwand)
//给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. Platzieren Sie die Die Anzahl der Raster, die hier in die Leinwand eingeschleift werden sollen, ist um eins größer als die angezeigte Anzahl, also Count+1-Werte, da beim Scrollen tatsächlich eines an der Außenseite vorhanden ist. Dadurch wird eine zyklische Bewegung gewährleistet. Was den Abstand zwischen den beiden Steuerelementen betrifft, muss das Raster festgelegt werden. Zu diesem Zeitpunkt wird das Steuerelement direkt in das Raster geworfen
//循环将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. Geben Sie Fügen Sie jedem Raster einen Animationseffekt hinzu. Dies ist der Effekt der Bewegung nach links
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. Beim Scrollen muss berechnet werden, welchem Raster das UserControl hinzugefügt wird zu, das heißt, welche Kontrolle als erste.
Wir legen den Indexwert scroll_index = 0 fest. Dies ist der Anfangszustand nach dem Scrollen: scroll_index = scroll_index + 1 - Uc_Count;
Dann beurteilen Sie beim Schleifen. Ist es das Ende der Anzeigeliste? Wenn ja, ist das zu füllende Steuerelement scroll_index %UcListSum.Count (Bildlaufindex, der Rest wird direkt von der Gesamtzahl übernommen). Wenn nicht, ist es scroll_index++ % UcListSum.Count (Bildlaufindex++, nimm den Rest direkt von der Gesamtsumme)
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); }
Im Code muss Folgendes beachtet werden: (uc.Parent as Grid).Children.Clear(), Wenn es nicht entfernt wird, wird eine Meldung angezeigt, dass es bereits zu einem anderen gehört und daher vom übergeordneten Element entfernt werden muss.
7. Das ausgeblendete Ereignis der Schaltfläche muss ausgeblendet werden. Tatsächlich bedeutet dies, dass das Element, das nicht mehr angezeigt wird, von der Gesamtzahl abgezogen wird 🎜>
Alle Codes lauten wie folgt:
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(); } } } }
Ungelöste Probleme
<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>
Ich möchte eine Schaltfläche hinzufügen, die beim Schweben der Maus angezeigt und beim Entfernen ausgeblendet wird. Ich habe jedoch festgestellt, dass dies nicht funktioniert. Der Grund dafür ist, dass der Wert erhöht wird von Sichtbarkeit hat sich geändert, aber der Wert von Button wird erst beim nächsten Mal angehängt, und zu diesem Zeitpunkt ist es bereits MouseLeave. Kann mir bitte jemand zeigen, wie ich dies ein- und ausblenden kann?
Das obige ist der detaillierte Inhalt vonBeispiel für die Implementierung wunderschöner Marquee-Spezialeffekte in WPF. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!