Walther
Walther

Reputation:

How do I scroll text in WPF textBlock control?

HI
I am new to WPF and I am looking for a solution to scroll text in a WPF application,
I tried some animation but I have a clipping problem
I found a possible solution to my problem in the following place:

http://social.msdn.microsoft.com/forums/en-US/wpf/thread/8330696e-7715-479e-8027-8d9925579a17/

but it is not clear to me what the variables TranslateTransformName, scrollfactor and tt should be..
Can somebody look at the code and help me to figure it out?
thanks

Wally

this is the code there: Code Block

<p class=MsoNoSpacing>&lt;
    <span class=SpellE>Viewbox</span>
    <span class=SpellE>OpacityMask</span> =&quot;{x
    <span
class=GramE>:Null</span> }&quot;
    <span class=SpellE>HorizontalAlignment</span> =&quot;Center&quot;
    <span class=SpellE>VerticalAlignment</span> =&quot;Stretch&quot;
Width=&quot;Auto&quot; Height=&quot;Auto&quot;
    <span class=SpellE>RenderTransformOrigin</span> =&quot;0.5,0.5&quot;
x:Name=&quot;container&quot; Stretch=&quot;Uniform&quot;
    <span class=SpellE>StretchDirection</span> =&quot;Both&quot;&gt;
</p>

<p class=MsoNoSpacing>
    <span style='mso-spacerun:yes'></span> &lt;
    <span
class=SpellE>Viewbox.RenderTransform</span> &gt;
</p>

<p class=MsoNoSpacing>
    <span style='mso-spacerun:yes'></span> &lt;
    <span
class=SpellE>TransformGroup</span> &gt;
</p>

<p class=MsoNoSpacing>
    <span style='mso-spacerun:yes'>
    </span> &lt;
    <span class=SpellE>ScaleTransform</span>
    <span class=SpellE>ScaleX</span> =&quot;1&quot;
    <span class=SpellE>ScaleY</span> =&quot;1&quot;/&gt;
</p>

<p class=MsoNoSpacing>
    <span style='mso-spacerun:yes'>
    </span> &lt;
    <span class=SpellE>SkewTransform</span>
    <span class=SpellE>AngleX</span> =&quot;0&quot;
    <span class=SpellE>AngleY</span> =&quot;0&quot;/&gt;
</p>

<p class=MsoNoSpacing>
    <span style='mso-spacerun:yes'>
    </span> &lt;
    <span class=SpellE>RotateTransform</span> Angle=&quot;0&quot;/&gt;
</p>

<p class=MsoNoSpacing>
    <span style='mso-spacerun:yes'>
    </span> &lt;
    <span class=SpellE>TranslateTransform</span> X=&quot;640&quot;
Y=&quot;0&quot;/&gt;
</p>

<p class=MsoNoSpacing>
    <span style='mso-spacerun:yes'></span> &lt;/
    <span
class=SpellE>TransformGroup</span> &gt;
</p>

<p class=MsoNoSpacing>
    <span style='mso-spacerun:yes'></span> &lt;/
    <span
class=SpellE>Viewbox.RenderTransform</span> &gt;
</p>

<p class=MsoNoSpacing>
    <span style='mso-spacerun:yes'></span> &lt;
    <span
class=SpellE>TextBlock</span>
    <span class=SpellE>RenderTransformOrigin</span> =&quot;0.5
    <span
class=GramE>,0.5</span> &quot;
    <span class=SpellE>HorizontalAlignment</span> =&quot;Center&quot;
x:Name=&quot;
    <span class=SpellE>tb</span> &quot;
    <span class=SpellE>VerticalAlignment</span> =&quot;Center&quot;
Width=&quot;Auto&quot; Height=&quot;Auto&quot;
    <span class=SpellE>FontSize</span> =&quot;50&quot;
    <span class=SpellE>TextWrapping</span> =&quot;
    <span class=SpellE>NoWrap</span> &quot;
Background=&quot;{x:Null}&quot; Foreground=&quot;#FFFFFFFF&quot;
Padding=&quot;0,0,0,10&quot; Text=&quot;0&quot;&gt;
</p>

<p class=MsoNoSpacing></p>

<p class=MsoNoSpacing>
    <span style='mso-spacerun:yes'></span> &lt;
    <span
class=SpellE>TextBlock.RenderTransform</span> &gt;
</p>

<p class=MsoNoSpacing>
    <span style='mso-spacerun:yes'>
    </span> &lt;
    <span class=SpellE>TransformGroup</span> &gt;
</p>

<p class=MsoNoSpacing>
    <span style='mso-spacerun:yes'>
    </span> &lt;
    <span class=SpellE>ScaleTransform</span>
    <span class=SpellE>ScaleX</span> =&quot;1&quot;
    <span class=SpellE>ScaleY</span> =&quot;1&quot;/&gt;
</p>

<p class=MsoNoSpacing>
    <span style='mso-spacerun:yes'>
    </span> &lt;
    <span class=SpellE>SkewTransform</span>
    <span class=SpellE>AngleX</span> =&quot;0&quot;
    <span class=SpellE>AngleY</span> =&quot;0&quot;/&gt;
</p>

<p class=MsoNoSpacing>
    <span style='mso-spacerun:yes'>
    </span> &lt;
    <span class=SpellE>RotateTransform</span> Angle=&quot;0&quot;/&gt;
</p>

<p class=MsoNoSpacing>
    <span style='mso-spacerun:yes'>
    </span> &lt;
    <span class=SpellE>TranslateTransform</span> X=&quot;640&quot;
Y=&quot;0&quot;/&gt;
</p>

<p class=MsoNoSpacing>
    <span style='mso-spacerun:yes'>
    </span> &lt;/
    <span class=SpellE>TransformGroup</span> &gt;
</p>

<p class=MsoNoSpacing>
    <span style='mso-spacerun:yes'></span> &lt;/
    <span
class=SpellE>TextBlock.RenderTransform</span> &gt;
</p>

<p class=MsoNoSpacing>
    <span style='mso-spacerun:yes'></span> &lt;/
    <span
class=SpellE>TextBlock</span> &gt;
</p>

<p class=MsoNoSpacing>
    <span style='mso-spacerun:yes'></span> &lt;/
    <span
class=SpellE>Viewbox</span> &gt;
</p>

<p class=MsoNoSpacing>
    <o:p>&nbsp;</o:p>
</p>

<p class=MsoNoSpacing>
    <o:p>&nbsp;</o:p>
</p>

<p class=MsoNoSpacing>
    <o:p>&nbsp;</o:p>
</p>

<p class=MsoNoSpacing>
    <o:p>&nbsp;</o:p>
</p>

Code Block private void StartAnimation(object sender, EventArgs e) { tb.Text = news;

        MainWindow.UpdateLayout();

        Double timeToTake = (MainWindow.Width + tb.ActualWidth) / scrollfactor;

        this.tb.RenderTransform = tt;
        Storyboard sb = new Storyboard();

        DoubleAnimation daX = new DoubleAnimation(MainWindow.Width, (0.0 - tb.ActualWidth), new Duration(TimeSpan.FromSeconds(timeToTake)));
        daX.RepeatBehavior = RepeatBehavior.Forever;

        Storyboard.SetTargetName(daX, TranslateTransformName);
        Storyboard.SetTargetProperty(daX, new PropertyPath(TranslateTransform.XProperty));
        sb.Children.Add(daX);
        sb.Begin(this.tb);
    }

Upvotes: 3

Views: 26609

Answers (3)

Junior Mayhe
Junior Mayhe

Reputation: 16411

You could scroll textblock with this code:

    <ScrollViewer Name="myScroll" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Hidden" HorizontalAlignment="Right" Width="414.403" Height="226.645" VerticalAlignment="Bottom">
        <Grid Name="Grid">
            <TextBlock Name="txbReceta" TextWrapping="Wrap"
                       MaxWidth="{Binding ElementName=Grid, Path=ActualWidth}" FontSize="20">
                Twitter is useless. Twitter is useless.
                Twitter is useless. Twitter is useless.
                Twitter is useless. Twitter is useless.
                Twitter is useless. Twitter is useless.
            </TextBlock>

        </Grid>
    </ScrollViewer>

In this case vertical scroll bar is hidden, you can put custom buttons to scroll up and down your textblock.

private void btnUp_Click(object sender, RoutedEventArgs e)
{
     myScroll.LineUp();
     myScroll.LineUp();
}

Upvotes: 1

Gishu
Gishu

Reputation: 136663

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;  
  }

Upvotes: 4

Jobi Joy
Jobi Joy

Reputation: 50038

http://jobijoy.blogspot.com/2008/08/wpf-custom-controls-marquee-control.html

You can check the idea behind this Marquee control. When you say to scroll the text inside the textBlock.. think about scrolling a long textblock inside a marqueee control. This control is a ContentControl which can scroll any Content inside.

Upvotes: 2

Related Questions