Here's a complete sample - verified that it works. I modified source posted here by Philipsh (minor changes to control layout to make it more presentable)
I kind of skipped the animation chapter in Programming WPF . So I can't explain how it works.. the book is not at hand. I'd be guessing at best if I tried to post answers..
XAML
<Window x:Class="transforms.Window1"
Title="Window2" SizeToContent="WidthAndHeight">
<DockPanel>
<StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal">
<TextBox x:Name="txtTexttoScroll">Enter some text to marquee</TextBox>
<Button x:Name="button1" Click="button1_Click">Start Scrolling</Button>
</StackPanel>
<Canvas Name="canvas1" Height="32" ClipToBounds="True" Background="AliceBlue" Width="200">
<TextBlock Canvas.Left="0" Canvas.Top="0" Height="31" Name="textBlock1" Width="{Binding ElementName=canvas1, Path=ActualWidth}" Text="Have a nice day!" FontSize="18.6666666666667" TextWrapping="NoWrap" VerticalAlignment="Center">
<TextBlock.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1"/>
<SkewTransform AngleX="0" AngleY="0"/>
<RotateTransform Angle="0"/>
<TranslateTransform x:Name="rtTTransform"/>
</TransformGroup>
</TextBlock.RenderTransform>
</TextBlock>
</Canvas>
</DockPanel>
</Window>
Button Click Event handler
private void button1_Click(object sender, RoutedEventArgs e)
{
double textBoxWidth = 10;
double pixelXFactor;
double canvaswidth = this.canvas1.Width;
double negXOffSet = 0;
double fromSecValue = 0;
double equSlope = 0.022546419;
double offSetY = 10.96286472;
double stringSize;
int textLen = txtTexttoScroll.Text.Length;
//Set the width of the text box according to the width (not length) of the text in it.
System.Globalization.CultureInfo enUsCultureInfo;
Typeface fontTF;
FormattedText frmmtText;
if (textLen > 0)
{
enUsCultureInfo = System.Globalization.CultureInfo.GetCultureInfo("en-us");
fontTF = new Typeface(this.textBlock1.FontFamily, this.textBlock1.FontStyle, this.textBlock1.FontWeight, this.textBlock1.FontStretch);
frmmtText = new FormattedText(txtTexttoScroll.Text, enUsCultureInfo, FlowDirection.LeftToRight, fontTF, this.textBlock1.FontSize, this.textBlock1.Foreground);
stringSize = frmmtText.Width;
if (stringSize < 100)
pixelXFactor = 1.02;
else
pixelXFactor = 1.01;
textBoxWidth = stringSize * pixelXFactor;
this.textBlock1.Width = textBoxWidth;
negXOffSet = textBoxWidth * -1;
fromSecValue = (stringSize * equSlope) + offSetY;
this.textBlock1.Text = txtTexttoScroll.Text;
Storyboard _sb = new Storyboard();
Duration durX = new Duration(TimeSpan.FromSeconds(fromSecValue));
DoubleAnimation daX = new DoubleAnimation(canvaswidth, negXOffSet, durX);
daX.RepeatBehavior = RepeatBehavior.Forever;
Storyboard.SetTargetName(daX, "rtTTransform");
Storyboard.SetTargetProperty(daX, new PropertyPath(TranslateTransform.XProperty));
_sb.Children.Add(daX);
_sb.Begin(this.textBlock1);
}
else
{
textBoxWidth = 1;
stringSize = 0;
}