2016-07-25 12 views
-1

Ich implementierte die Lösung für this question, in einem Fenster mit XAML unten angegeben. Ich versuche, einen Scrolling Marquee-Text-Effekt für ein Label zu machen:WPF-Laufschrift Textanimation scrollt über andere Kontrollen

<Window x:Class="WpfMarqueeText.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:wpfMarqueeText="clr-namespace:WpfMarqueeText" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="200"/> 
      <RowDefinition Height="*"/> 
     </Grid.RowDefinitions> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="500"/> 
      <ColumnDefinition Width="*"/> 
     </Grid.ColumnDefinitions> 

     <Grid Grid.Row="0" Grid.Column="0" Background="Aqua"> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="200"/> 
       <ColumnDefinition Width="300"/> 
      </Grid.ColumnDefinitions> 

      <Ellipse Grid.Column="0" Margin="5,3,5,3" Fill="#b933ad"/> 
      <Label Grid.Column="0" Content="Z" Foreground="White" FontFamily="HelveticaBold" FontSize="150" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="5,3,5,3"/> 

      <Grid Grid.Column="1"> 
       <Grid.RowDefinitions> 
        <RowDefinition Height="Auto"/> 
        <RowDefinition Height="*"/> 
       </Grid.RowDefinitions> 

       <Grid Grid.Row="0"> 
        <Grid.RowDefinitions> 
         <RowDefinition Height="Auto"/> 
         <RowDefinition Height="Auto"/> 
        </Grid.RowDefinitions> 
        <Grid.ColumnDefinitions> 
         <ColumnDefinition Width="Auto"/> 
         <ColumnDefinition Width="*"/> 
        </Grid.ColumnDefinitions> 

        <Label Grid.Row="0" Grid.Column="0" Content="Some Info:" FontFamily="HelveticaBold" FontSize="18" FontWeight="Bold" Margin="5,3,5,3"/> 

        <StackPanel Grid.Row="0" Grid.Column="1" Orientation="Horizontal" x:Name="stack"> 
         <StackPanel.Resources> 
          <wpfMarqueeText:NegatingConverter x:Key="NegatingConverter" /> 
          <Storyboard x:Key="slide"> 
           <DoubleAnimation From="0" To="{Binding Width, ElementName=canvas, Converter={StaticResource NegatingConverter}}" Duration="00:00:10" 
           Storyboard.TargetProperty="X" 
           Storyboard.TargetName="transferCurreny" 
           RepeatBehavior="Forever"/> 
          </Storyboard> 
         </StackPanel.Resources> 
         <StackPanel.RenderTransform> 
          <TranslateTransform x:Name="transferCurreny" X="0"/> 
         </StackPanel.RenderTransform> 
         <StackPanel.Triggers> 
          <EventTrigger RoutedEvent="StackPanel.Loaded"> 
           <BeginStoryboard Storyboard="{StaticResource slide}" /> 
          </EventTrigger> 
          <EventTrigger RoutedEvent="StackPanel.SizeChanged"> 
           <BeginStoryboard Storyboard="{StaticResource slide}" /> 
          </EventTrigger> 
         </StackPanel.Triggers> 

         <Canvas x:Name="canvas" Width="{Binding ActualWidth, ElementName=stack}"> 
          <Label FontFamily="HelveticaBold" FontSize="18" Margin="5,3,5,3" x:Name="Label1" Content="Blah blah blah" Canvas.Left="0"/> 
          <Label Name="Label2" Content="{Binding Content, ElementName=Label1}" FontFamily="HelveticaBold" FontSize="18" Margin="5,3,5,3" Canvas.Left="{Binding ActualWidth, ElementName=stack}"/> 
         </Canvas> 

        </StackPanel> 
       </Grid> 
      </Grid> 
     </Grid> 
    </Grid> 
</Window> 

Sie müssen auch die NegatingConverter Klasse im Code-Behind definieren:

public class NegatingConverter : IValueConverter 
{ 

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (value is double) 
     { 
      return -((double)value); 
     } 
     return value; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (value is double) 
     { 
      return +(double)value; 
     } 
     return value; 
    } 
} 

Dies erzeugt den gewünschten EFFEKT, aber der Text Animation rollt über die anderen Elemente der Benutzeroberfläche, wie unten in den Bildern zu sehen (sorry, ich habe nicht genug rep Bilder posten):

http://tinypic.com/r/df8zeu/9 http://tinypic.com/r/2inc3r/9

Gibt es also eine Möglichkeit, die Animation so zu korrigieren, dass der Text nur innerhalb der Grenzen der Rasterspalte scrollt, in der er enthalten ist, oder innerhalb der Grenzen des Labels selbst? Danke für jede Hilfe!

+0

http://www.codeproject.com/Articles/48267/Making-a-Simple-Marquee-Text-Control-Drip-Animatio sollte Ihnen helfen – Akanksha

+0

Ehrfürchtig, vielen Dank für das Posten. Ich werde versuchen, dies in meinem Projekt umzusetzen. – lunaa

Antwort

0

Der Artikel von Akanksha als Reaktion auf meine OP verknüpft zeigt, wie ein Benutzersteuerelement erstellt wird, das einen sauberen, scrollenden Texteffekt erzeugt. Sie können auch 4 verschiedene Bildlaufrichtungen angeben, links < -> rechts und oben < -> runter. Ich werde für andere meine Implementierung hier geben:

XAML für MarqueeTextUserControl:

<UserControl x:Class="AaronLuna.Common.UI.UserControls.MarqueeTextUserControl" 
     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" 
     mc:Ignorable="d" Loaded="UserControl_Loaded"> 

    <Canvas ClipToBounds="True" Name="CanvasMain"> 
     <TextBlock Name="TextBlockMain"/> 
    </Canvas> 

</UserControl> 

-Code für MarqueeTextUserControl:

namespace AaronLuna.Common.UI.UserControls 
{   
    public partial class MarqueeTextUserControl 
    { 
     public MarqueeTextUserControl() 
     { 
      InitializeComponent(); 
      CanvasMain.Height = Height; 
      CanvasMain.Width = Width; 
     } 

     public ScrollDirection ScrollDirection { get; set; } 
     public double ScrollDurationInSeconds { get; set; } 
     public String Text { set { TextBlockMain.Text = value; }} 

     private void UserControl_Loaded(object sender, RoutedEventArgs e) 
     { 
      ScrollText(ScrollDirection); 
     } 

     public void ScrollText(ScrollDirection scrollDirection) 
     { 
      switch (scrollDirection) 
      { 
       case ScrollDirection.LeftToRight: 
        LeftToRightMarquee(); 
        break; 
       case ScrollDirection.RightToLeft: 
        RightToLeftMarquee(); 
        break; 
       case ScrollDirection.TopToBottom: 
        TopToBottomMarquee(); 
        break; 
       case ScrollDirection.BottomToTop: 
        BottomToTopMarquee(); 
        break; 
      } 
     } 

     private void LeftToRightMarquee() 
     { 
      double height = CanvasMain.ActualHeight - TextBlockMain.ActualHeight; 
      TextBlockMain.Margin = new Thickness(0, height/2, 0, 0); 

      var doubleAnimation = new DoubleAnimation 
      { 
       From = -TextBlockMain.ActualWidth, 
       To = CanvasMain.ActualWidth, 
       RepeatBehavior = RepeatBehavior.Forever, 
       Duration = new Duration(TimeSpan.FromSeconds(ScrollDurationInSeconds)) 
      }; 

      TextBlockMain.BeginAnimation(Canvas.LeftProperty, doubleAnimation); 
     } 

     private void RightToLeftMarquee() 
     { 
      double height = CanvasMain.ActualHeight - TextBlockMain.ActualHeight; 
      TextBlockMain.Margin = new Thickness(0, height/2, 0, 0); 

      var doubleAnimation = new DoubleAnimation 
      { 
       From = -TextBlockMain.ActualWidth, 
       To = CanvasMain.ActualWidth, 
       RepeatBehavior = RepeatBehavior.Forever, 
       Duration = new Duration(TimeSpan.FromSeconds(ScrollDurationInSeconds)) 
      }; 

      TextBlockMain.BeginAnimation(Canvas.RightProperty, doubleAnimation); 
     } 

     private void TopToBottomMarquee() 
     { 
      double width = CanvasMain.ActualWidth - TextBlockMain.ActualWidth; 
      TextBlockMain.Margin = new Thickness(width/2, 0, 0, 0); 

      var doubleAnimation = new DoubleAnimation 
      { 
       From = -TextBlockMain.ActualHeight, 
       To = CanvasMain.ActualHeight, 
       RepeatBehavior = RepeatBehavior.Forever, 
       Duration = new Duration(TimeSpan.FromSeconds(ScrollDurationInSeconds)) 
      }; 

      TextBlockMain.BeginAnimation(Canvas.TopProperty, doubleAnimation); 
     } 

     private void BottomToTopMarquee() 
     { 
      double width = CanvasMain.ActualWidth - TextBlockMain.ActualWidth; 
      TextBlockMain.Margin = new Thickness(width/2, 0, 0, 0); 

      var doubleAnimation = new DoubleAnimation 
      { 
       From = -TextBlockMain.ActualHeight, 
       To = CanvasMain.ActualHeight, 
       RepeatBehavior = RepeatBehavior.Forever, 
       Duration = new Duration(TimeSpan.FromSeconds(ScrollDurationInSeconds)) 
      }; 

      TextBlockMain.BeginAnimation(Canvas.BottomProperty, doubleAnimation); 
     } 
    } 

    public enum ScrollDirection 
    { 
     LeftToRight, 
     RightToLeft, 
     TopToBottom, 
     BottomToTop 
    } 
} 

XAML Auftraggeber:

<UserControl x:Class="MarqueeTextExampleUserControl" 
     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:userControls="clr-namespace:AaronLuna.Common.UI.UserControls;assembly=AaronLuna.Common" 
     mc:Ignorable="d"> 

    <DockPanel> 
     <Label Content="Some Info:"/> 
     <userControls:MarqueeTextUserControl x:Name="MarqueeTextBlock"/> 
    </DockPanel> 

</UserControl> 

Client-Code:

MarqueeTextBlock.Text = "Blah blah blah"; 
MarqueeTextBlock.ScrollDirection = ScrollDirection.RightToLeft; 
MarqueeTextBlock.ScrollDurationInSeconds = 10; 
0

Dies ist eine quick and dirty-Lösung:

ändern Label zu

<Label Grid.Row="0" Grid.Column="0" Content="Some Info:" FontFamily="HelveticaBold" FontSize="18" FontWeight="Bold" Margin="5,3,5,3" Panel.ZIndex="99" Background="Aqua"/> 

Die Panel.ZIndex die Label nach vorne bringt. Und die Background nicht transparent macht das gewünschte Aussehen. Die Grenzen sind immer noch nicht perfekt, aber dies sollte Ihnen einen Hinweis geben, wie man mit Ebenen umgehen kann

+0

Danke! Ich habe etwas ähnliches versucht, aber den ZIndex auf die falschen XAML-Elemente angewendet, denke ich. – lunaa