65.9K
CodeProject 正在变化。 阅读更多。
Home

实现基于 Silverlight 的“垂直”跑马灯

starIconstarIconemptyStarIconemptyStarIconemptyStarIcon

2.00/5 (1投票)

2015年10月1日

CPOL

3分钟阅读

viewsIcon

6581

实现基于 Silverlight 的“垂直”跑马灯

最初发布于 http://bobhardister.com/archive/2009/03/31/implementing-a-silverlight-based-lsquoverticalrsquo-tickertape.aspx

引言

我目前的一个项目需要一个商业头条新闻的“混搭”。为此,我希望有一个区域,头条新闻从底部进入,其他头条新闻向上滚动,并在顶部消失。如果没有新的头条新闻,则第一个头条新闻会出现在底部。

通常情况下,我喜欢从基础开始构建,构建解决方案的一部分,然后在此基础上进行扩展。因此,这篇文章不涉及收集新闻——我将把这部分留到另一篇文章中。这篇文章将只处理滚动区域。

创建滚动区域

为了让 Silverlight 的一个区域可以滚动,我们可以使用 <ScrollViewer> 标签。这个标签会替换掉我们想要滚动的任何标记。对于新闻提要或这个例子,这将是一个 StackPanel,其方向将设置为 Vertical

<ScrollViewer x:Name="ScrollRegion"
VerticalScrollBarVisibility="Hidden"
HorizontalScrollBarVisibility="Hidden"
BorderThickness="0"
Background="White"
Height="150"
Width="200"
Cursor="Hand"> 
<StackPanel x:Name="ItemsStack" Orientation="Vertical" > 
</StackPanel> 
</ScrollViewer> 

上面的代码创建了一个可滚动的区域,其中包含一个没有边框、背景为白色的堆栈面板。目前,堆栈面板是空的——这是因为内容将由代码后台添加。

创建我们的“示例”标题

由于这是一个示例,为了便于理解,我没有使用真实的新闻标题,而是使用了圆桌骑士。这被定义为一个 string 数组,如下所示:

String[] Knights = { 
"King Arthur", 
"Sir Lancelot", 
"Sir Gawain", 
"Sir Geraint", 
"Sir Gareth", 
"Sir Gaheris", 
"Sir Bedivere", 
"Sir Galahad", 
"Sir Kay", 
"Sir Bors de Ganis", 
"Sir Lamorak", 
"Sir Tristan", 
"Sir Percivale"
};

添加我们的“示例”标题

向我们的堆栈面板添加条目非常简单。我们首先获取堆栈面板的引用,创建一个文本块,将文本设置为我们的下一个条目,并将文本块添加到 StackPanel 的 Children 中。

StackPanel sp = FindName("ItemsStack") as StackPanel;
TextBlock tb = new TextBlock();
tb.Text = Knights[0];
sp.Children.Add(tb);

设置自动添加条目的功能

我们需要我们的应用程序每隔一段时间自动向新闻提要添加新的条目。为此,我们需要一个在预定时间间隔后触发的东西,为此我们使用 DispatchTimer 类。

DispatcherTimer dispatchTimer;
.
.
.
public Page()
{
InitializeComponent();
.
.
.
dispatchTimer = new DispatcherTimer();
dispatchTimer.Interval = new TimeSpan(0, 0, 30); // 30 Seconds
dispatchTimer.Tick +=new EventHandler(dispatchTimer_Tick);
dispatchTimer.Start();

现在我们需要在每次间隔触发时向显示中添加新的标题,为此我们定义一个 Tick 事件的处理程序。

添加与上面的部分相同,但添加多于第一个条目时,必须处理一些额外的活动。首先,我们需要知道新标题占据的空间大小。在将文本添加到它之后,Silverlight 会通过 ‘ActualHeight’ 属性提供它所占用的高度。

UsedHeight += tb.ActualHeight; // increment the area that has been filled up till now.

接下来,我们检查添加条目是否需要滚动显示区域,为此我们将我们的 ‘UsedHeight’ 与 StackPanel 的实际高度进行比较。

if (UsedHeight > sp.ActualHeight)
{
.

现在如果它已经滚动,某些条目将从区域的顶部消失。因此,应用程序循环遍历每个条目,以查看条目的任何部分是否已经超出顶部,然后将其删除。

for (i = 0; i < sp.Children.Count; i++)
{
TextBlock tbVisible = sp.Children[i] as TextBlock;
ItemHeight += tbVisible.ActualHeight;
if ((ItemHeight <= UsedHeight - sp.ActualHeight) || 
((ItemHeight - tbVisible.ActualHeight)) < (UsedHeight - sp.ActualHeight))
{
UsedHeight -= tbVisible.ActualHeight; // remove from the used height, the space taken by the item
sp.Children.RemoveAt(i); // now remove the item from the stackpanel
}
}

我们还从我们的已用空间计数器中删除该条目所占用的空间。

这就是创建可滚动区域的方法。我稍后会处理实际的新闻条目的收集,并可能会在那个时候发布它是如何工作的。

© . All rights reserved.