0

In our WPF application, we need a simple marquee text control that is lightweight and efficient in terms of performance. I tried to do so with a DoubleAnimation but it was using a lot of resources (mostly from CPU). I also tried setting the TextBlock's Text property and removing a character from the beginning every 100 nano seconds. That didn't boost the performance either.
So what's the best and most efficient approach to designing a marquee text control in WPF? (We're using .Net 4.0)

SepehrM
  • 961
  • 1
  • 16
  • 42
  • have you tried with simple html ? or javascript – MethodMan Jun 09 '14 at 18:06
  • @DJKRAZE In a WPF application? – Servy Jun 09 '14 at 18:08
  • @DJKRAZE You mean using a Web Browser? We can't use the web browser since our application has transparency and .Net 's default web browser (which is just a wrapper around IE) doesn't support transparent host windows and free alternatives only support 32 bit environment. So for now, we are unable to do so. – SepehrM Jun 09 '14 at 18:09
  • 1
    The last time I did something like this it was along the lines of the answer on [this question](http://stackoverflow.com/questions/15323163/wpf-marquee-text-animation), is what you're trying similar and still seeing the same performance issue? – Chris W. Jun 09 '14 at 19:04
  • @ChrisW. Actually my method is the same and I had seen this post before. But frankly, this time, I just copy-pasted the code and it seems efficient and its performance is way better than my approach. So I'm investigating why my implementation was slow and I'll report back as soon as I figure it out. – SepehrM Jun 09 '14 at 19:44
  • I had horrible cpu usage until I added an on-off dependency property to turn it off when it wasn't used. But if yours has to be visible all the time, that technique will not help. You can *try* modifying the control template of the progress bar however. – Gayot Fow Jun 09 '14 at 23:03
  • @ChrisW. That method seems good enough. But do you know how to get it working when the text is long and cannot be fit in the TextBlock? In that case the 2 TextBlocks overlap and things get messy. – SepehrM Jun 10 '14 at 07:37
  • Are you trying to make like a news ticker? – Chris W. Jun 10 '14 at 13:39
  • @ChrisW. Yes, exactly! – SepehrM Jun 10 '14 at 16:43
  • [Check this out](http://www.jarloo.com/rumormill4/), or you could make the same type of thing in pure xaml, I just dont know when I'd have time to throw an example together. – Chris W. Jun 10 '14 at 18:12

1 Answers1

2

Thanks to @Chris W. and this question here is what I finally came up with (I wanted left to right animation for rtl languages):

<Window x:Class="WpfApplication9.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication9"
        Title="MainWindow" Height="83" Width="222">
    <Grid x:Name="layoutRoot">
        <Canvas x:Name="canvas">
            <TextBlock Text="StackOverflow is just awesome!" FontSize="25"  x:Name="tb1" Canvas.Left="-131" Loaded="tb1_Loaded">
                <TextBlock.Resources>
                    <Storyboard x:Key="slide">
                        <DoubleAnimation From="0" To="{Binding Width, ElementName=tb1}" Duration="00:00:4"
                      Storyboard.TargetProperty="X"
                      Storyboard.TargetName="transferCurreny"
                      RepeatBehavior="Forever"/>
                    </Storyboard>
                </TextBlock.Resources>
                <TextBlock.RenderTransform>
            <TranslateTransform x:Name="transferCurreny" X="0"/>
        </TextBlock.RenderTransform>
                <TextBlock.Triggers>
                    <EventTrigger RoutedEvent="TextBlock.Loaded">
                        <BeginStoryboard Storyboard="{StaticResource slide}" />
                    </EventTrigger>
                </TextBlock.Triggers>
            </TextBlock>
        </Canvas>
    </Grid>
</Window>

Code-Behind:

using System.Windows;

namespace WpfApplication9
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        private void tb1_Loaded(object sender, RoutedEventArgs e)
        {
            tb1.Width = tb1.ActualWidth;
        }
    }
}
Community
  • 1
  • 1
SepehrM
  • 961
  • 1
  • 16
  • 42