Puedo desplazar texto con TranslateTransform
pero cuando la animación está a punto de terminar, me gustaría que comience de nuevo. Como una serpiente 🙂
Esto es lo que tengo:
Esto es lo que me gustaría:
Algo como esto debería hacer el truco.
Puede agregar un Canvas
al StackPanel
con 2 TextBlocks
uno configurado en la posición 0 y uno configurado en el ActualWidth
del StackPanel
, y cuando el primer bloque de texto pase a estar fuera de pantalla, el otro bloque aparecerá en la vista.
La razón por la que utilicé Canvas
es porque Canvas
es el único elemento que realmente admite ClipToBounds="false"
esto permite que el 2nd TextBlock
sea visible incluso si se coloca fuera de los límites del Canvas
También necesitamos un IValueConverter
para obtener el valor negativo correcto si desea desplazarse de derecha a izquierda.
También agregué un activador de evento en SizeChanged
por lo que si la ventana SizeChanged
tamaño, los valores de la animación se actualizarán correctamente.
Código:
namespace WpfApplication9 { /// /// Interaction logic for MainWindow.xaml /// public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } } public class NegatingConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if (value is double) { return -((double)value); } return value; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if (value is double) { return +(double)value; } return value; } } }
Xaml:
Resultado:
Editar: de izquierda a derecha
El código en la respuesta anterior no produce desplazamiento continuo. Aquí está el código para desplazamiento suave continuo.
XAML:
Código VB detrás:
Imports System.Windows.Media.Animation Public Enum Texts BoxOne BoxTwo End Enum Class Window1 Private dubAnim As New DoubleAnimation() Private dubAnim2 As New DoubleAnimation() Private NewsTimer As New Windows.Threading.DispatcherTimer() Dim leadText As Texts = Texts.BoxOne Private Sub Window1_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded dubAnim.From = ViewingBox.ActualWidth dubAnim.To = -BoxOne.ActualWidth dubAnim.SpeedRatio = 0.05 AddHandler dubAnim.Completed, AddressOf dubAnim_Completed Timeline.SetDesiredFrameRate(dubAnim, 320) BoxOne.BeginAnimation(Canvas.LeftProperty, dubAnim) dubAnim2.From = ViewingBox.ActualWidth dubAnim2.To = -BoxTwo.ActualWidth dubAnim2.SpeedRatio = 0.05 Timeline.SetDesiredFrameRate(dubAnim2, 320) AddHandler dubAnim2.Completed, AddressOf dubAnim2_Completed AddHandler NewsTimer.Tick, AddressOf NewsTimer_Tick NewsTimer.Interval = New TimeSpan(0, 0, 0.9) NewsTimer.Start() End Sub Private Sub NewsTimer_Tick(ByVal sender As Object, ByVal e As EventArgs) Dim BoxOneLocation As Point = BoxOne.TranslatePoint(New Point(0, 0), ViewingBox) Dim BoxTwoLocation As Point = BoxTwo.TranslatePoint(New Point(0, 0), ViewingBox) If leadText = Texts.BoxOne Then Dim loc As Double = BoxOneLocation.X + BoxOne.ActualWidth If loc < ViewingBox.ActualWidth / 1.5 Then BoxTwo.BeginAnimation(Canvas.LeftProperty, dubAnim2) NewsTimer.Stop() End If Else Dim loc As Double = BoxTwoLocation.X + BoxTwo.ActualWidth If loc < ViewingBox.ActualWidth / 1.5 Then BoxOne.BeginAnimation(Canvas.LeftProperty, dubAnim) NewsTimer.Stop() End If End If End Sub Private Sub dubAnim_Completed(ByVal sender As Object, ByVal e As EventArgs) leadText = Texts.BoxTwo NewsTimer.Start() End Sub Private Sub dubAnim2_Completed(ByVal sender As Object, ByVal e As EventArgs) leadText = Texts.BoxOne NewsTimer.Start() End Sub End Class
Extendiendo la respuesta de sa_ddam213 , esta es una revisión de la primera animación (de derecha a izquierda). Esto funcionará para cadenas largas. 🙂