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

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

starIconstarIconstarIconemptyStarIconemptyStarIcon

3.00/5 (1投票)

2009 年 4 月 1 日

CPOL

3分钟阅读

viewsIcon

16224

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

引言

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

通常情况下,当我工作时,我喜欢从基础开始构建,逐步构建解决方案的一部分。因此,这篇文章不会涉及收集新闻——我将把这部分留到另一篇文章中。这篇文章将只处理滚动区域。

创建滚动区域

要在 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" 
};

添加我们的“示例”标题

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

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

设置自动添加条目的功能

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

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.