0
votes

I have a Custom Ticker Control which works well with static values, but to have it working with dynamic values I need to do this in code because I have to delay the storyboard execution until the TextBlock has been rendered. I need to transfer the following XAML into C# but it doesn't work:

<Canvas x:Name="PART_TickerCanvas" Grid.Row="1" Width="128" ClipToBounds="True">
                        <TextBlock x:Name="PART_TickerTextBlock">
                            <TextBlock.Triggers>
                                <EventTrigger RoutedEvent="Loaded">
                                    <BeginStoryboard>
                                        <Storyboard>
                                            <DoubleAnimation
                        Storyboard.TargetName="TickerTranslateTransform"
                        Storyboard.TargetProperty="X"
                        From="{Binding ElementName=TickerCanvas, Path=ActualWidth}" To="{Binding ElementName=PART_TickerTextBlock, Path=RenderSize.Width, Converter={StaticResource TextBlockWidthConverter}}" Duration="0:0:10"
                        RepeatBehavior="Forever"/>
                                        </Storyboard>
                                    </BeginStoryboard>
                                </EventTrigger>
                            </TextBlock.Triggers>
                            <TextBlock.RenderTransform>
                                <TranslateTransform x:Name="TickerTranslateTransform" X="{Binding ElementName=PART_TickerCanvas, Path=ActualWidth}" Y="0" />
                            </TextBlock.RenderTransform>
                        </TextBlock>
                    </Canvas>

The converter simply negates the width.

This is my C# approach:

public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        if (Template != null)
        {
            _tickerTextBlock = Template.FindName("PART_TickerTextBlock", this) as TextBlock;
            _tickerCanvas = Template.FindName("PART_TickerCanvas", this) as Canvas;
            Dispatcher.BeginInvoke(new Action(() => {if (_tickerCanvas != null && _tickerTextBlock != null) StartTickerAnimation(); }), DispatcherPriority.ContextIdle, null);                
        }
    }

private void StartTickerAnimation()
    {
        var doubleAnimation = new DoubleAnimation
        {
            From = _tickerCanvas.ActualWidth,
            To = -_tickerTextBlock.RenderSize.Width,
            RepeatBehavior = RepeatBehavior.Forever,
            Duration = new Duration(new TimeSpan(0, 0, 10))
        };

        _tickerTextBlock.RenderTransform = new TranslateTransform(_tickerCanvas.ActualWidth, 0);
        RegisterName("TickerTranslateTransform", _tickerTextBlock.RenderTransform);          

        var storyBoard = new Storyboard();
        storyBoard.Children.Add(doubleAnimation);
        storyBoard.SetValue(Storyboard.TargetNameProperty, "TickerTranslateTransform");
        storyBoard.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath(TranslateTransform.XProperty.Name));
        storyBoard.SetValue(Storyboard.TargetProperty, _tickerTextBlock.RenderTransform);
        _tickerTextBlock.BeginStoryboard(_storyBoard);
    }

I am pretty sure that the DoubleAnimation is correct in C# but something wrong afterwards. Any help would be greatly appreciated.

1

1 Answers

1
votes

You don't need a Storyboard.

Start an animation of the X property directly like this:

_tickerTextBlock.RenderTransform.BeginAnimation(
    TranslateTransform.XProperty, doubleAnimation);