WPF中的连续文本Ticker

时间:2014-02-21 08:41:38

标签: wpf textblock

Gaurang Gaurang Gaurang Gaurang Gaurang Gaurang Gaurang Gaurang Gaurang Gaurang Gaurang

我正在WPF中创建一个文本自动收录器。我能够永远地将文本从右向左移动但我的问题是,我想要无缝地移动相同的文本以创建上述效果(就像股票交易所的股票代码)。上述文字必须无止境地进行。

我怎样才能实现它?

3 个答案:

答案 0 :(得分:4)

我会创建多个ContentControl(或您想要使用的任何控件)并将它们放在水平方向的StackPanel中。 ContentControl的数量取决于内容的大小。因此,我会创建一个ContentControl,分配内容,然后在其上调用Measure(...)以确定所需的大小。根据窗口或父控件的大小,您可以计算需要创建的控件数量以填充整个空间。这看起来像这样:

Initial state (1):  +------------- Parent Control -------------+
                    |                                          |
                    |+---------+ +---------+ +---------+ +-----|---+ +---------+
                    || Gaurang | | Gaurang | | Gaurang | | Gaur|ng | | Gaurang |
                    |+---------+ +---------+ +---------+ +-----|---+ +---------+
                    |                                          |^^^^^^^^^^^^^^^^
                    +------------------------------------------+  not visible!

然后我会将带有StackPanel的{​​{1}}放入ContentControls并为Canvas的{​​{1}}属性设置动画,以便它移动到期望的方向。

现在的问题是,StackPanel的结尾会移动到可见区域,并且不再显示Canvas.Left

StackPanel

您可以通过限制ContentControl的{​​{1}}属性的动画来解决此问题,以便它只会移动到第一个Bad state (2): +------------- Parent Control -------------+ | | +---------+ +-------|-+ +---------+ +---------+ +---------+ | | Gaurang | | Gauran| | | Gaurang | | Gaurang | | Gaurang | | +---------+ +-------|-+ +---------+ +---------+ +---------+ | ^^^^^^^^^^^^^^^^^^^^| | not visible +------------------------------------------+ ^^^^ BAD 移出可见区域之外:

StackPanel

一旦达到此状态,动画应从头开始,即返回初始状态(1)。这样,您将始终在状态(1)和状态(3)之间进行动画处理。由于所有Canvas.Left具有相同的大小,因此用户可以获得无限移动动画的印象。当然,动画应配置为无限重复。

注意:我没有对此进行测试,但我认为它应该可以正常工作。现在我测试了它,它确实有效。这是我的测试代码:

ContentControl

将其粘贴到空白WPF窗口并运行它。您可以增加窗口的大小以查看实际发生的情况 - 动画仅移动一个Final state (3): +------------- Parent Control -------------+ | | +---------+|+---------+ +---------+ +---------+ +-----|---+ | Gaurang ||| Gaurang | | Gaurang | | Gaurang | | Gaur|ng | +---------+|+---------+ +---------+ +---------+ +-----|---+ | | +------------------------------------------+ 然后从头开始。

请注意ContentControl是使用<Canvas> <StackPanel x:Name="stack" Orientation="Horizontal"> <StackPanel.Triggers> <EventTrigger RoutedEvent="Loaded"> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" From="0" To="-68" FillBehavior="Stop" RepeatBehavior="Forever"/> </Storyboard> </BeginStoryboard> </EventTrigger> </StackPanel.Triggers> <ContentControl Content="Gaurang" Margin="4" Width="60"/> <ContentControl Content="Gaurang" Margin="4" Width="60"/> <ContentControl Content="Gaurang" Margin="4" Width="60"/> <ContentControl Content="Gaurang" Margin="4" Width="60"/> <ContentControl Content="Gaurang" Margin="4" Width="60"/> <ContentControl Content="Gaurang" Margin="4" Width="60"/> <ContentControl Content="Gaurang" Margin="4" Width="60"/> <ContentControl Content="Gaurang" Margin="4" Width="60"/> <ContentControl Content="Gaurang" Margin="4" Width="60"/> </StackPanel> </Canvas> + ContentControl + To="-68"计算的。在您的情况下,您必须在代码隐藏中手动添加Width,确定它们的宽度并相应地设置动画的Margin.Left属性。

答案 1 :(得分:3)

所以从阅读你的问题来看,我不确定你想要什么。你想要一个文本,滚动出文本框,然后像大多数字幕控件/函数一样重新开始。

或者你想要一些在你的文本框中反复运行的文本,从头到尾填写它?然后使用一个不可检测的给定循环? :)

代码背后:

//单行动画。

private void LeftToRightMarqueeOnTextBox()
{
  string Copy = " "+TextBoxMarquee.Text;
  double TextGraphicalWidth = new FormattedText(TextBoxMarquee.Text, System.Globalization.CultureInfo.CurrentCulture, System.Windows.FlowDirection.LeftToRight, new Typeface(TextBoxMarquee.FontFamily.Source), TextBoxMarquee.FontSize, TextBoxMarquee.Foreground).WidthIncludingTrailingWhitespace;
  //BorderTextBoxMarquee.Width = TextGraphicalWidth + 5;

  ThicknessAnimation ThickAnimation = new ThicknessAnimation();
  ThickAnimation.From = new Thickness(TextBoxMarquee.ActualWidth, 0, 0, 0);
  ThickAnimation.To = new Thickness(-TextGraphicalWidth, 0, 0, 0);
  ThickAnimation.RepeatBehavior = RepeatBehavior.Forever;
  ThickAnimation.Duration = new Duration(TimeSpan.FromSeconds(3));
  TextBoxMarquee.BeginAnimation(TextBox.PaddingProperty, ThickAnimation);
}

OR

//句子重复动画,没有间隙。

string Copy = " "+TextBoxMarquee.Text;
  double TextGraphicalWidth = new FormattedText(Copy, System.Globalization.CultureInfo.CurrentCulture, System.Windows.FlowDirection.LeftToRight, new Typeface(TextBoxMarquee.FontFamily.Source), TextBoxMarquee.FontSize, TextBoxMarquee.Foreground).WidthIncludingTrailingWhitespace;
  double TextLenghtGraphicalWidth = 0;
  //BorderTextBoxMarquee.Width = TextGraphicalWidth + 5;
  while (TextLenghtGraphicalWidth < TextBoxMarquee.ActualWidth)
  {
    TextBoxMarquee.Text += Copy;
    TextLenghtGraphicalWidth = new FormattedText(TextBoxMarquee.Text, System.Globalization.CultureInfo.CurrentCulture, System.Windows.FlowDirection.LeftToRight, new Typeface(TextBoxMarquee.FontFamily.Source), TextBoxMarquee.FontSize, TextBoxMarquee.Foreground).WidthIncludingTrailingWhitespace;
  }
  TextBoxMarquee.Text += " "+TextBoxMarquee.Text;
  ThicknessAnimation ThickAnimation = new ThicknessAnimation();
  ThickAnimation.From = new Thickness(0, 0, 0, 0);
  ThickAnimation.To = new Thickness(-TextGraphicalWidth, 0, 0, 0);
  ThickAnimation.RepeatBehavior = RepeatBehavior.Forever;
  ThickAnimation.Duration = new Duration(TimeSpan.FromSeconds(2));
  TextBoxMarquee.BeginAnimation(TextBox.PaddingProperty, ThickAnimation);

XAML:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Canvas ClipToBounds="True" Name="canMain" Background="Transparent">
        <Grid Width="{Binding ElementName=canMain, Path=ActualWidth}" >
            <Grid.ColumnDefinitions>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <TextBlock Grid.Row="0" Name="TextBlockMarquee" Text="This is my animated text" />
            <Border Grid.Row="1" BorderBrush="Black" BorderThickness="1">
                <TextBox ClipToBounds="True" Name="TextBoxMarquee" Text="lars er en god skakspiller, der tænker længere end de andre" BorderBrush="Transparent"/>
            </Border>
        </Grid>
    </Canvas>
</Grid>

基本上忽略大部分XAML。重要的是文本框中文本的长度。 Hav没有找到通用解决方案,这就是为什么我的From Thickness是基于数字的。

但只需要确定这就是你要找的东西:)

修改/更新:

所以现在尝试一下,我已经更新了代码..希望它可以工作,但是从一些测试看来它似乎:)只有你需要确定的是整个文本框被填写,然后我正在做它的副本,我将从字符串图形长度循环两个文本:)(

修改/更新: 我已经添加了我的最终解决方案,希望这有任何帮助。

修改/更新

忘记更新我的重复解决方案,因此它没有切断并使循环可见..现在完成:)

答案 2 :(得分:0)

我创建了一个应用程序来显示RSS提要作为自动收报机,就像股票代码一样从右向左移动。将其修改为股票代码应该是微不足道的。 RumorMill4

该链接有一个简短的教程和所有源代码,但您需要知道的一件事是这个自动收报机在队列中工作,因此一旦项目滚动,它就会被排队。那时你可以检查数据是否仍然相关并更新它然后将其添加回队列进行显示。

不幸的是,此实现不支持DataBinding,因此当自动收报机当前正在移动项目时,您无法调整值。 (多年前写过,RSS源不像股票那样改变,因此不是优先考虑的事项。)