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

没有 XAML 的 Silverlight

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.74/5 (10投票s)

2008年11月20日

CPOL

4分钟阅读

viewsIcon

40365

downloadIcon

216

无XAML的Silverlight,只是一个用于图形和娱乐的游乐场。

ScreenShot.jpg

引言

Silverlight很棒,可以用模板和用户控件做很多事情。但是,如果您想制作一个游戏,或者只是一个炫酷的演示,例如节日的雪花效果呢?那么XAML还有什么用呢?让我们摆脱它。

创建一个新的Silverlight项目

首先创建一个新的Silverlight项目,就像你习惯的那样。点击菜单中的文件->新建->项目...,或者按Ctrl+Shift+N。

FileNewProject.jpg

从Silverlight项目类型中选择Silverlight应用程序,并为其取一个有趣的名字。我把它命名为SilverlightWithoutXaml。然后,按确定按钮。

CreateProject1.jpg

您可以创建一个动态数据驱动的ASP.NET MVC Web项目来托管您出色的Silverlight游戏,但为了本文的简洁性,我们选择对话框中的“自动生成”选项。

CreateProject2.jpg

删除XAML

现在,等待片刻,让Visual Studio创建我们将在几分钟内删除的漂亮的XAML文件……Visual Studio显示的项目如下图所示。继续删除这两个XAML文件即可。*.cs文件将自动删除。

DefaultProject.jpg

除了某些配置文件和生成的文件外,项目现在为空。因为没有代码的Silverlight不会做太多事情,所以我们现在要添加一个新的类。右键单击项目,然后转到添加->类...您可以随意命名它,但在示例中,我将其命名为WithoutXamlApp

AddClass.jpg

Silverlight需要一个启动应用程序的地方。因此,刚刚添加到解决方案的类需要从System.Windows.Application派生。

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Collections.Generic;

namespace SilverlightWithoutXaml
{
    public class WithoutXamlApp : Application
    {
    
    }
}

接下来,我们需要添加一个HTML文件来托管Silverlight控件。按照您刚才为类所做的那样添加一个HTML文件。右键单击项目并选择添加->新建项... 选择HTML文件模板并将其命名为StartPage.htm或您更习惯的任何名称。将以下内容添加到HTML文件的body中

<object id="ID" type="application/x-silverlight-2" width="600" height="400">
    <param name="source" value="bin/debug/SilverlightWithoutXaml.xap" />
    <param name="background" value="#00000000" />
</object>

配置项目

要运行应用程序,您需要对该项目的属性进行一些更改。右键单击项目并转到属性。确保启动对象设置为SilverlightWithoutXaml.WithoutXamlApp

SetStartObj.jpg

转到调试选项卡,然后按特定页面单选按钮旁边的带省略号的按钮。从对话框中选择StartPage.htm并按确定。太棒了!按F5构建并运行应用程序以查看它是否有效。如果您的浏览器中出现一个带有黑色正方形和中间Silverlight加载动画的白色HTML页面,则表示一切正常。如果没有,请再次阅读上述内容,或在下方发表评论,我会尽力帮助您解决错误。

addHtml.jpg

娱乐时间

好了,现在您拥有了一个无XAML的Silverlight应用程序!接下来是什么?我知道,您看到了顶部的屏幕截图,并且您在想:“嘿!我也想要在我的Silverlight应用程序中添加白点!”让我们添加一些。

在我们启动动画循环并进行有趣的事情之前,我们必须等到Silverlight完成加载并启动应用程序。幸运的是,发生这种情况时会触发一个事件。应用程序类中Silverlight运行的第一个内容是构造函数。这将是注册启动事件的理想场所。将以下代码添加到WithoutXamlApp类中

public WithoutXamlApp()
{
    this.Startup += new StartupEventHandler(WithoutXamlApp_Startup);
}

void WithoutXamlApp_Startup(object sender, StartupEventArgs e)
{
}

让我们添加一个画布进行绘制。此画布需要分配给应用程序的this.RootVisualRootVisual是一个UIElement,它保存应用程序的主要UI,即可视化树的根。将以下代码添加到WithoutXamlApp_Startup方法中。这将使用黑色背景初始化根Canvas

this.RootVisual = new Canvas()
{
    Background = new SolidColorBrush(Colors.Black)
};

对于动画循环,我们将使用DispatcherTimer。启动此计时器时,它会启动一个线程,并在给定的时间间隔内触发一个事件。此计时器的优点是它非常易于实现。将以下四行代码添加到WithoutXamlApp_Startup方法中

DispatcherTimer Timer = new DispatcherTimer();
Timer.Interval = new TimeSpan(300);
Timer.Tick += new EventHandler(Timer_Tick);
Timer.Start();

我选择的300毫秒间隔可以提供流畅的动画。Timer.Tick的事件处理程序如下所示。最后一行启动计时器。从那时起,每隔0.03秒调用一次Tick事件。

void Timer_Tick(object sender, EventArgs e)
{
}

我们快完成了。最后的代码片段由三个部分组成。一个循环遍历并更新所有点并记住需要从可视化树中删除的点,第二个执行点的实际删除,最后一个在随机X位置向Canvas添加一个新点。让我们来看一下

void Timer_Tick(object sender, EventArgs e)
{
    // list of dots to be removed
    List<Ellipse> ElToRemove = new List<Ellipse>();
     foreach (Ellipse child in ((Canvas)this.RootVisual).Children)
    {
        // if a dot leaves the canvas area
        if (Canvas.GetTop(child) > 400)
            ElToRemove.Add(child); // add it to be removed
        else
        {   //update the location of the dots
            Canvas.SetTop(child, Canvas.GetTop(child) + 2);
            Canvas.SetLeft(child, Canvas.GetLeft(child) + 
                                    (rnd.NextDouble() * 4) - 2);
        }
    }

    //remove the dots from the visual tree
    foreach (Ellipse item in ElToRemove)
    {
        ((Canvas)this.RootVisual).Children.Remove(item);
    }

    //add a new dot at a random x-location, 
    //with a random size
    int size = rnd.Next(3, 15);
    Ellipse el = new Ellipse()
    {
        Width = size,
        Height = size,
        Stroke = new SolidColorBrush(Colors.White),
        StrokeThickness = size
    };
    Canvas.SetLeft(el, rnd.NextDouble() * 750 - 150);
    Canvas.SetTop(el, -15);
    //and add it to the visual tree
    ((Canvas)this.RootVisual).Children.Add(el);
}

要使此代码工作,您需要在类的开头声明private Random rnd = new Random((int)DateTime.Now.Ticks);。这将为我们提供真正的随机数。

现在按F5,享受动画吧!

接下来呢?

从这里可以做很多事情。我一直计划做的一件事是使用无XAML的Silverlight控件来更改运行时的HTML DOM。而且,我正在考虑编写一个光线投射引擎,作为Wolfenstein 3D克隆的核心。我甚至可能会就此写一篇文章。

同时,享受Silverlight的乐趣!

历史

  • 2008-11-20 - 初次上传。
© . All rights reserved.