Silverlight 3 - 1. Application (1)

Silverlight 和 WPF 一脉相承,很多东西基本类似或一致。对了,Silverlight 早期的名字叫 WPF/E,由此可见一斑。Silverlight 拥有自己的 CLR / DLR,还有一个具有相当规模的的 BCL 库。从某种意义上来说,它几乎就是个 "嵌入式操作系统"。用 Silverlight 开发一个 RIA 方式的 NetOS,应该没啥问题,远比现在的 WebOS 要 "酷" 很多。

Silverlight 除了可以执行基于 CLR / DLR 的托管代码外,还支持用 JavaScript API 来调用。不过既然其主打是 RIA,我们自然没理由放弃 C#,而改用 JavaScript 来开发应用了。

Silverlight Applicaton Model 对使用过 WPF 或者 WinForm 的程序员来说,都不会陌生。

1. 生命周期

(1) 用户访问包含 Silverlight 应用的页面。
(2) Silverlight Plug-in 被载入,下载 Silverlight XAP 文件。
(3) Silverlight Plug-in 从 XAP 中读取 AppMainfest.xml,创建运行环境并载入程序集文件。
(4) Silverlight Plug-in 创建 Application 对象实例 (App.xaml, App.xaml.cs)。
(5) 通过构造方法触发 Application.Startup 事件,该事件将创建 Root Visual,这通常是应用的主页面。
(6) 执行应用程序功能。
(7) 当用户关闭浏览器、网页跳转、刷新,或者用 JavaScript 移除 Silverlight 都会导致当前 Application 关闭,并触发 Exit 事件。

2. Application.Events

打开 App.xaml.cs,你会看到相关的事件处理代码。

public partial class App : Application
{
  public App()
  {
    this.Startup += this.Application_Startup;
    this.Exit += this.Application_Exit;
    this.UnhandledException += this.Application_UnhandledException;

    InitializeComponent();
  }
}

(1) Application.StartUp

StartUp 事件用于指定 RootVisual 对象实例。需要注意的是,RootVisual 仅在第一次修改时有效,也就是说它是一种特殊的 "只读" 模式。
private void Application_Startup(object sender, StartupEventArgs e)
{
  this.RootVisual = new MainPage();
}

试试看。
public partial class MainPage : UserControl
{
  public MainPage()
  {
    InitializeComponent();
  }

  private void Button_Click(object sender, RoutedEventArgs e)
  {
    Application.Current.RootVisual = new UserControl();
    MessageBox.Show((Object.ReferenceEquals(Application.Current.RootVisual, this)).ToString());
  }
}

尽管对 RootVisual 没有触发异常,但输出结果表明,RootVisual 依然指向 MainPage。作为变通手段,我们可以用下面这种方式来替换主页面。
private void Application_Startup(object sender, StartupEventArgs e)
{
  this.RootVisual = new Grid();
  (this.RootVisual as Grid).Children.Add(new MainPage());
}

RootVisual 不能改,那就该 RootVisual.Children 好了。

除了指定 RootVisual 外,我们还可以处理初始化参数。这类似 GUI / CUI 的执行参数 Main (string[] args)。在包含 Silverlight 的 HTML 页面,我们可以指定相关的参数。
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
  ...  
  <param name="initParams" value="a=1,b=Hello" />
  ...
</object>

参数名称 "initParams",使用 "," 分割多个 KeyValuePair。
private void Application_Startup(object sender, StartupEventArgs e)
{
  this.RootVisual = new MainPage();

  var sb = new System.Text.StringBuilder();
  foreach (var kv in e.InitParams)
  {
    sb.AppendFormat("{0}={1}/n", kv.Key, kv.Value);
  }

  MessageBox.Show(sb.ToString());
}

(2) Application.Exit

Exit 事件使得我们在关闭应用时,可以执行一些额外的处理,比如存储相关数据。
private void Application_Exit(object sender, EventArgs e)
{
  MessageBox.Show("Exit!");
}

很好。无论是关闭页面,刷新页面还是跳转到其他页,我们都能看到这个可爱的 "Exit!"。

(3) Application.UnhandledException

UnhandledException 中的注释很好,它给那些不愿深究的 "懒人" 们一个很好的提示。通过 e.Handle 我们可以在处理异常后继续执行应用。ReportErrorToDOM() 还展示了如何和 HtmlPage 进行交互,包括执行 JavaScript 代码。
private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
  // If the app is running outside of the debugger then report the exception using
  // the browser's exception mechanism. On IE this will display it a yellow alert 
  // icon in the status bar and Firefox will display a script error.
  if (!System.Diagnostics.Debugger.IsAttached)
  {
    // NOTE: This will allow the application to continue running after an exception has been thrown
    // but not handled. 
    // For production applications this error handling should be replaced with something that will 
    // report the error to the website and stop the application.
    e.Handled = true;
    Deployment.Current.Dispatcher.BeginInvoke(delegate { ReportErrorToDOM(e); });
  }
}

private void ReportErrorToDOM(ApplicationUnhandledExceptionEventArgs e)
{
  try
  {
    string errorMsg = e.ExceptionObject.Message + e.ExceptionObject.StackTrace;
    errorMsg = errorMsg.Replace('"', '/'').Replace("/r/n", @"/n");

    HtmlPage.Window.Eval("throw new Error(/"Unhandled Error in Silverlight Application " + errorMsg + "/");");
  }
  catch (Exception)
  {
  }
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值