wpf WPF中的连续文本代码
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21929344/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Continuous text Ticker in WPF
提问by Gaurang
Gaurang Gaurang Gaurang Gaurang Gaurang Gaurang Gaurang Gaurang Gaurang Gaurang Gaurang
高朗高朗高朗高朗高朗高朗高朗高朗高朗高朗高朗高朗高朗高朗高朗高朗高朗高朗高朗高朗高朗高朗高朗高朗高朗高朗高朗高朗高朗高朗高朗高朗高朗
I am working in WPF to create a text ticker. I am able to move the text from right to left forever but my problem is, that I want to move the same text seamlessly to create the above effect(Just like the stock exchange ticker). The above text must move endlessly.
我正在 WPF 中创建一个文本自动收报机。我可以永远将文本从右向左移动,但我的问题是,我想无缝移动相同的文本以创建上述效果(就像证券交易所股票代码一样)。上面的文字必定无止境。
How can I achieve it?
我怎样才能实现它?
采纳答案by Max Mazur
So from reading your question i'm not really sure what you want. Do you want a text, that scrolls out of the textbox, and starts over, like most marquee controls/functions.
因此,通过阅读您的问题,我不确定您想要什么。您是否想要一个文本,滚动出文本框并重新开始,就像大多数选取框控件/功能一样。
Or do you want some text that runs over and over in your textbox, filling it out from start till end? and then with a given loop that is undectectable? :)
或者你想要一些在你的文本框中一遍又一遍地运行的文本,从头到尾填写?然后使用无法检测的给定循环?:)
Code behind:
后面的代码:
//Single line animation.
//单行动画。
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
或者
//Sentence Repeat animation with no gaps.
//没有间隙的句子重复动画。
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:
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>
Basically ignore most of the XAML. Whats important is the lenght of the Text in the Textbox. Havn't found a generic solution, thats why my From Thickness is number based.
基本上忽略大部分 XAML。重要的是文本框中文本的长度。还没有找到通用的解决方案,这就是为什么我的 From Thickness 是基于数字的。
But just had to be sure that this was what you were looking for :)
但只需要确保这就是您要找的东西:)
EDIT/UPDATE:
编辑/更新:
So try it out now, i've updated the code.. Hopefully it works, but from a few test it seemed like it :) Only thing that you need to be sure of is that the entire textbox is filled out, then i'm doing a copy of it, and i'll loop the two text from the strings graphical lenght :)(
所以现在试试吧,我已经更新了代码......希望它有效,但从一些测试来看,它似乎是这样的:) 你唯一需要确定的是整个文本框都被填满了,然后我'我做一个副本,我将从字符串图形长度中循环两个文本:)(
EDIT/UPDATE:I've added my final solutions hope this was of any help.
编辑/更新:我已经添加了我的最终解决方案,希望这对您有所帮助。
EDIT/Update
编辑/更新
Forgot to update my Repeat solution so it didn't cut off and make the loops visible.. Done now :)
忘记更新我的重复解决方案,所以它没有切断并使循环可见..现在完成:)
回答by gehho
I would create multiple ContentControls (or whatever controls you want to use) and put them in a StackPanelwith horizontal direction. The number of ContentControls depends on the size of the content. Therefore, I would create one ContentControl, assign the content, and then call Measure(...)on it to determine the size it needs. Depending on the size of the window or parent control, you can calculate how many controls you need to create to fill the entire space. This would look something like this:
我会创建多个ContentControls(或您想使用的任何控件)并将它们放在StackPanel水平方向上。ContentControls的数量取决于内容的大小。因此,我会创建一个ContentControl,分配内容,然后调用Measure(...)它来确定它需要的大小。根据窗口或父控件的大小,您可以计算需要创建多少个控件来填充整个空间。这看起来像这样:
Initial state (1): +------------- Parent Control -------------+
| |
|+---------+ +---------+ +---------+ +-----|---+ +---------+
|| Gaurang | | Gaurang | | Gaurang | | Gaur|ng | | Gaurang |
|+---------+ +---------+ +---------+ +-----|---+ +---------+
| |^^^^^^^^^^^^^^^^
+------------------------------------------+ not visible!
Then I would put the StackPanelwith the ContentControlsinto a Canvasand animate the StackPanel's Canvas.Leftproperty, so that it moves into the desired direction.
然后我将StackPanelwithContentControls放入 aCanvas并为StackPanel'sCanvas.Left属性设置动画,使其移动到所需的方向。
Now the problem is that the end of the StackPanelwill move into the visible area and there will be no more ContentControlto show:
现在的问题是,StackPanel将移动到可见区域的末尾将不再ContentControl显示:
Bad state (2): +------------- Parent Control -------------+
| |
+---------+ +-------|-+ +---------+ +---------+ +---------+ |
| Gaurang | | Gauran| | | Gaurang | | Gaurang | | Gaurang | |
+---------+ +-------|-+ +---------+ +---------+ +---------+ |
^^^^^^^^^^^^^^^^^^^^| |
not visible +------------------------------------------+
^^^^
BAD
You can fix this by restricting the animation of the StackPanel's Canvas.Leftproperty, so that it only moves until the first ContentControlwas moved out of the visible area:
您可以通过限制StackPanel'sCanvas.Left属性的动画来解决这个问题,这样它只会在第一个ContentControl被移出可见区域之前移动:
Final state (3): +------------- Parent Control -------------+
| |
+---------+|+---------+ +---------+ +---------+ +-----|---+
| Gaurang ||| Gaurang | | Gaurang | | Gaurang | | Gaur|ng |
+---------+|+---------+ +---------+ +---------+ +-----|---+
| |
+------------------------------------------+
Once this state is reached, the animation should start from the beginning, i.e. go back to the initial state (1). This way, you will always animate between state (1) and state (3). Since all ContentControls have the same size, the user gets the impression of an infinitely moving animation. Of course, the animation should be configured to repeat infinitely.
一旦达到此状态,动画应从头开始,即返回到初始状态 (1)。这样,您将始终在状态 (1) 和状态 (3) 之间进行动画处理。由于所有的ContentControls 都具有相同的大小,因此用户会得到一个无限移动动画的印象。当然,动画应该配置为无限重复。
Note: I did not test this, but I think it should work.Now I did test it, and it works. Here is my test code:
注意:我没有对此进行测试,但我认为它应该可以工作。现在我确实测试了它,它有效。这是我的测试代码:
<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>
Paste this into a blank WPF Window and run it. You can increase the size of the window to see what really happens - the animation only moves by one ContentControland then starts from the beginning.
将其粘贴到一个空白的 WPF 窗口中并运行它。您可以增加窗口的大小以查看实际发生的情况 - 动画仅移动一个ContentControl,然后从头开始。
Note that the To="-68"is calculated using Width+ Margin.Left+ Margin.Right. In your case, you would have to add the ContentControls manually in code-behind, determine their width and set the animation's Toproperty accordingly.
需要注意的是,To="-68"使用计算Width+ Margin.Left+ Margin.Right。在您的情况下,您必须ContentControl在代码隐藏中手动添加s,确定它们的宽度并相应地设置动画的To属性。
回答by Kelly
I created an application to display RSS feeds as a ticker that moves right to left just like a stock ticker. It should be trivial to modify it to be a stock ticker instead. RumorMill4
我创建了一个应用程序来将 RSS 提要显示为一个像股票行情一样从右向左移动的行情。将其修改为股票代码应该是微不足道的。RumorMill4
The link has a brief tutorial and all the source code, but the one thing you will need to know is this ticker works off a Queue, so once an item has scrolled off it is De-queued. At that time you could check if the data is still relevant and update it then add it back to the queue for display.
该链接有一个简短的教程和所有源代码,但您需要知道的一件事是此股票代码在队列中工作,因此一旦项目滚动离开,它就会出队。那时您可以检查数据是否仍然相关并更新它,然后将其添加回队列以供显示。
Unfortunately this implementation does not support DataBinding so you cannot adjust the values while the ticker is currently moving the item. (wrote it years ago, and RSS feeds don't change like stocks do, so wasn't a priority.)
不幸的是,此实现不支持数据绑定,因此当股票代码当前正在移动项目时,您无法调整值。(多年前写的,RSS 提要不会像股票那样变化,所以不是优先事项。)

