摘要:在Silverlight中所有应用都可以以一种叫做OOB(Out of browser)模式的方式脱离浏览器运行,在OOB模式下应用程序将获得更多的信任,甚至可以和windows API通信,今天就来看一下如何构建OOB应用。
主要内容:
什么是OOB 构建OOB应用 自定义OOB窗口 OOB应用升级 一、什么是OOBSilverlight out of browser从字面理解就是脱离浏览器的应用,是可以安装到本地的运行在浏览器外的应用,是一个具有独立窗口的web应用。在OOB模式下silverlight看起来更像是C/S应用,但是它却具有web应用的特性。这样一来就可以让用户像在C/S系统中一样体验绚丽、丰富的Web特性。相比浏览其中运行silverlight来讲,oob除了运行方式不同之外,还会获得更多的权限信任、更多的本地化内容,这样以来很多浏览器中很难做到甚至无法做到的事情在oob中也同样可以实现。目前很多silverlight应用都支持oob模式,例如pptv剧场版就是一个很好的案例:
二、构建OOB应用在Visual Studio中构建OOB应用很简单,只需要简单几步设置即可完成。在此之前先看一下没有对项目做OOB设置之前的情况。
简单建一个silverlight应用,运行之后的状态如下:
点击右键发现当前只有一个菜单:
OK,现在对项目进行OOB设置:
在项目中右键PropertIEs,进入Silverlight选项,点击Enable running application out of browser,此时下面的"Out of browser Setting"按钮将变成可用状态,点击此按钮d出下面的设置窗口:
然后做如下设置,这里设置了窗口大小、所需图标以及Trust权限(选中该项后安装时需要用户确认):
图标:
设置完成后可以直接启动此项目(SilverlightApplicationOOB)进行调试而不必在对于的web项目(SilverlightApplicationOOB.Web)中运行,效果如下:
这里为了对比不妨在浏览器中查看效果:
可以看到在右键菜单中多了一个选项,点击此选项可以直接将程序安装到计算机上,安装时由于之前设置了Trust所以需要用户确认以及设置开始和桌面快捷方式:
安装完成后就可以直接看OOB下的效果:
为了让用户有更好的体验,使用右键进行安装未免不够专业并且用户体验较差,一般情况下会选择使用程序进行安装控制,代码很简单:
using System;using System.Net;using System.windows;using System.windows.Controls;using System.windows.documents;using System.windows.Ink;using System.windows.input;using System.windows.Media;using System.windows.Media.Animation;using System.windows.Shapes;using System.Net.networkinformation;namespace Cmj.MyWeb.MySilverlight.SiverlightOOB{ public class OOBInstall { public bool IsInstalled() { if (Application.Current.InstallState == InstallState.Installed) { return true; } else { return false; } } /// <summary> /// 程序安装 /// </summary> public voID Install() { if (!Application.Current.IsRunningOutOfbrowser) { if (Application.Current.InstallState != InstallState.Installed) { Application.Current.Install(); } else { MessageBox.Show("程序已安装!","系统提示",MessageBoxbutton.OK); } } //调用InstallStateChanged事件将安装状态传递给调用者 Application.Current.InstallStateChanged += new EventHandler(Current_InstallStateChanged); } voID Current_InstallStateChanged(object sender,EventArgs e) { //此处调用自定义事件 OnInstalling(sender,new InstallStateArgs()); } //自定义一个事件来修改安装时状态 public delegate voID InstallingHandler(object sender,InstallStateArgs e); public event InstallingHandler Installing; public voID OnInstalling(object sender,InstallStateArgs e) { if (Installing != null) { Installing(sender,e); } } } public class InstallStateArgs:EventArgs { public InstallState State { get { return Application.Current.InstallState; } } }}
在程序中通过Application.Current.Install()方法进行安装,当然在这之前最好进行状态检测看程序是不是已经在浏览器外运行。另外在安装时也可以使用Application.Current.InstallState跟踪安装状态。有了上面的代码接下来就可在界面放一个按钮,然后在不同的状态下动态给用户不同的提示。
XAML代码:
<UserControl x:Class="SilverlightApplicationOOB.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/Expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:cmj="clr-namespace:Cmj.MyWeb.MySilverlight.MyUserControl;assembly=Cmj.MyWeb.MySilverlight" mc:Ignorable="d" d:DesignHeight="300" d:DesignWIDth="400" Loaded="UserControl_Loaded"> <GrID x:name="LayoutRoot" Background="#FFCDDBE8"> <GrID.RowDeFinitions> <RowDeFinition Height="60"></RowDeFinition> <RowDeFinition Height="*"></RowDeFinition> </GrID.RowDeFinitions> <GrID.ColumnDeFinitions> <ColumnDeFinition WIDth="*"></ColumnDeFinition> </GrID.ColumnDeFinitions> <TextBlock Height="42" HorizontalAlignment="Center" name="txtblkDescription" Text="Silverlight Out Of browser" VerticalAlignment="Center" Foreground="#FFF21FE1" FontSize="20" /> <button Content="Install" GrID.Row="1" Height="23" HorizontalAlignment="Center" name="btnInstall" VerticalAlignment="Center" WIDth="75" Click="btnInstall_Click" /> </GrID></UserControl>
CS代码:
using System;using System.Collections.Generic;using System.linq;using System.Net;using System.windows;using System.windows.Controls;using System.windows.documents;using System.windows.input;using System.windows.Media;using System.windows.Media.Animation;using System.windows.Shapes;using Cmj.MyWeb.MySilverlight.SiverlightOOB;namespace SilverlightApplicationOOB{ public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); } OOBInstall oob = new OOBInstall(); private voID UserControl_Loaded(object sender,RoutedEventArgs e) { if (oob.IsInstalled()) { this.btnInstall.Visibility = Visibility.Collapsed; } else { this.btnInstall.Visibility=Visibility.Visible; } } private voID btnInstall_Click(object sender,RoutedEventArgs e) { oob.Install(); } }}
安装完后如何卸载呢,事实上可以按照一般C/S程序的方式卸载,或者在Web中运行此程序右键进行删除。
三、自定义OOB窗口在上面或许您已经看到了,OOB设置窗口中有以下窗口风格设置:
这个选项在很多时候是很有用的,上面窗口使用的是默认风格(Default),窗口 *** 作(最大化、最小化、关闭、移动、窗口大小设置)均调用windows API。当然,相应的界面也显得呆板一些,如果你的应用想要拥有炫酷的界面,那么Default或许无法满足你的需求。但是silverlight已经为您预留了接口,后面No border和borderless Round Corners就给你无限的遐想空间。下面就来看一下如何自定义一个OOB窗口。
要自定义窗口其实就是要实现最小化、最大化、关闭、窗口移动、窗口大小设置功能,除了窗口大小设置功能之外其他功能均在标题栏实现,而窗口大小的resize *** 作一般是放到窗口右下角进行的,因此为了便于复用,接下来会创建两个用户控件:Titlebar和Resizebutton。
创建一个silverlight class library项目Cmj.MyWeb.MySilverlight,添加一个UserControl,命名为Titlebar。Titlebar就是标题栏部分,实现最小化、最大化、关闭、窗口移动 *** 作。标题栏主要包括ico、标题文本、最小化按钮、最大化按钮和关闭按钮几部分,这里不妨使用GrID布局将其分为一行五列,分别对应ico、标题和三个按钮。为了使控件在使用时自适应宽度,可以将标题部分所在的列设置为"*",并且注意不要给UserControl设置WIDth和Height属性,只需要设置DesignWIDth和DesignHeight即可。在第一列中放一个Image控件用于显示应用程序图标,在第二列中放一个TextBlock显示标题内容,其余三列放三个button按钮用于实现窗口最小化、最大化和关闭。然后准备四个图标作为按钮的背景(最大化按钮需要最大化状态和正常状态两个图标):
有了这些之后接下来就需要实现各部分功能了。最小化、最大化只需要设置MainWindow的windowstate即可;关闭时调用Close方法;而拖动 *** 作可以交给GrID来做,在GrID的MouseleftbuttonDown中调用MainWindow的DragMove方法。需要注意的是最大化按钮的图标有两种状态,需要根据不同的状态动态改变图标。
到此为止Titlebar的功能基本上已经实现,但作为一个通用控件最好把一些内容交给使用者来 *** 作以便增加控件灵活性,这里定义Icon、Title、Background属性用户设置标题栏图标、标题内容和标题栏背景。下面是Titlebar前台XAML和后台CS代码:
<UserControl x:Class="Cmj.MyWeb.MySilverlight.MyUserControl.Titlebar" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/Expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="24" d:DesignWIDth="400"> <GrID x:name="LayoutRoot" Background="Gray" MouseleftbuttonDown="LayoutRoot_MouseleftbuttonDown"> <GrID.ColumnDeFinitions> <ColumnDeFinition WIDth="auto" /> <ColumnDeFinition WIDth="*" /> <ColumnDeFinition WIDth="auto" /> <ColumnDeFinition WIDth="auto"/> <ColumnDeFinition WIDth="auto"/> </GrID.ColumnDeFinitions> <GrID.RowDeFinitions> <RowDeFinition Height="22" /> </GrID.RowDeFinitions> <Image GrID.Row="0" GrID.Column="0" name="imgIcon" WIDth="16" Height="16" Source="/Cmj.MyWeb.MySilverlight;component/Images/cmjlogo.png" /> <TextBlock GrID.Row="0" GrID.Column="1" margin="5,4" Text="CMJ Title bar Control" name="txtblkTitle" HorizontalAlignment="left" /> <button GrID.Row="0" GrID.Column="2" Height="18" HorizontalAlignment="Right" name="btnMiniMize" VerticalAlignment="top" WIDth="18" margin="2,2,2" Click="btnMiniMize_Click"> <Image name="imgMinimize" Source="/Cmj.MyWeb.MySilverlight;component/Images/minizime.png" /> </button> <button GrID.Row="0" GrID.Column="3" Height="18" HorizontalAlignment="left" name="btnMaxiMize" VerticalAlignment="top" WIDth="18" margin="2,2" Click="btnMaxiMize_Click"> <Image name="imgMaximize" Source="/Cmj.MyWeb.MySilverlight;component/Images/maximize.png" /> </button> <button GrID.Row="0" GrID.Column="4" Height="18" HorizontalAlignment="Right" name="btnClose" VerticalAlignment="top" WIDth="18" margin="2,5,2" Click="btnClose_Click" > <Image name="imgClose" Source="/Cmj.MyWeb.MySilverlight;component/Images/close.png" /> </button> </GrID></UserControl>
using System;using System.Collections.Generic;using System.linq;using System.Net;using System.windows;using System.windows.Controls;using System.windows.documents;using System.windows.input;using System.windows.Media;using System.windows.Media.Animation;using System.windows.Media.Imaging;using System.windows.Shapes;namespace Cmj.MyWeb.MySilverlight.MyUserControl{ public partial class Titlebar : UserControl { public Titlebar() { InitializeComponent(); } private BitmAPImage binormal = new BitmAPImage(new Uri("../Images/maximizeMax.png",UriKind.relative)); private BitmAPImage biMax = new BitmAPImage(new Uri("../Images/maximize.png",UriKind.relative)); public ImageSource Icon { get { return this.imgIcon.source; } set { this.imgIcon.source = value; } } public string Title { get { return this.txtblkTitle.Text; } set { this.txtblkTitle.Text = value; } } public color Backgroundcolor { get { return ((SolIDcolorBrush)this.LayoutRoot.Background).color; } set { ((SolIDcolorBrush)this.LayoutRoot.Background).color = value; } } public new Brush Background { get { return this.LayoutRoot.Background; } set { this.LayoutRoot.Background=value; } } public new double Height { get { return this.LayoutRoot.Height; } private set { this.LayoutRoot.Height = value; } } private voID btnMiniMize_Click(object sender,RoutedEventArgs e) { Application.Current.MainWindow.windowstate = windowstate.Minimized; } private voID btnMaxiMize_Click(object sender,RoutedEventArgs e) { if (Application.Current.MainWindow.windowstate == windowstate.Maximized) { this.imgMaximize.source = biMax; Application.Current.MainWindow.windowstate = windowstate.normal; } else { this.imgMaximize.source = binormal; Application.Current.MainWindow.windowstate = windowstate.Maximized; } this.WIDth = Application.Current.MainWindow.WIDth; } private voID btnClose_Click(object sender,RoutedEventArgs e) { Application.Current.MainWindow.Close(); } private voID LayoutRoot_MouseleftbuttonDown(object sender,MousebuttonEventArgs e) { Application.Current.MainWindow.DragMove(); } }}
Titlebar在上面已经完成接下来就来实现窗口的resize *** 作,在项目中再添加一个UserControl命名为Resizebutton,在Resizebutton中放置Image控件来显示拖拽图标
,接下来设置UserControl的MouseleftbuttonDown事件调用MainWindow的DragResize方法实现拖拽功能,在MouseEnter和MouseLeave事件中更改鼠标指针为SizenesW和Arrow,代码如下:<UserControl x:Class="Cmj.MyWeb.MySilverlight.MyUserControl.Resizebutton" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/Expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="16" d:DesignWIDth="16" MouseleftbuttonDown="UserControl_MouseleftbuttonDown" MouseEnter="UserControl_MouseEnter" MouseLeave="UserControl_MouseLeave"> <GrID x:name="LayoutRoot" Background="transparent"> <Image name="imgResize" WIDth="16" Height="16" Source="/Cmj.MyWeb.MySilverlight;component/Images/resize.png" /> </GrID></UserControl>
using System;using System.Collections.Generic;using System.linq;using System.Net;using System.windows;using System.windows.Controls;using System.windows.documents;using System.windows.input;using System.windows.Media;using System.windows.Media.Animation;using System.windows.Shapes;namespace Cmj.MyWeb.MySilverlight.MyUserControl{ public partial class Resizebutton : UserControl { public Resizebutton() { InitializeComponent(); } private voID UserControl_MouseleftbuttonDown(object sender,MousebuttonEventArgs e) { Application.Current.MainWindow.DragResize(WindowResizeEdge.Bottomright); } private voID UserControl_MouseEnter(object sender,MouseEventArgs e) { this.Cursor = Cursors.SizenesW; } private voID UserControl_MouseLeave(object sender,MouseEventArgs e) { this.Cursor = Cursors.Arrow; } }}
两个控件都已经开发完毕,剩下的工作就是如何使用了。在SilverlightApplicationOOB中引用Cmj.MyWeb.MySilverlight的dll。接着在Main.Xaml中添加命名空间:xmlns:cmj="clr-namespace:Cmj.MyWeb.MySilverlight.MyUserControl;assembly=Cmj.MyWeb.MySilverlight"
(控件前缀任意命名,这里命名为cmj),然后在Main.Xaml中定义Titlebar和Resizebutton并设置相关属性:
<UserControl x:Class="SilverlightApplicationOOB.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/Expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:cmj="clr-namespace:Cmj.MyWeb.MySilverlight.MyUserControl;assembly=Cmj.MyWeb.MySilverlight" mc:Ignorable="d" d:DesignHeight="300" d:DesignWIDth="400" Loaded="UserControl_Loaded"> <GrID x:name="LayoutRoot" Background="#FFCDDBE8"> <GrID.RowDeFinitions> <RowDeFinition Height="23"></RowDeFinition> <RowDeFinition Height="*"></RowDeFinition> <RowDeFinition Height="16"></RowDeFinition> </GrID.RowDeFinitions> <GrID.ColumnDeFinitions> <ColumnDeFinition WIDth="*"></ColumnDeFinition> </GrID.ColumnDeFinitions> <cmj:Titlebar GrID.Row="0" title="CMJ Control" Icon="/Cmj.MyWeb.MySilverlight;component/Images/cmjlogo.png" Background="#FFCDDBE8" /> <GrID GrID.Row="1" name="GrdContent" Background="#FFADB9CD" margin="3,3,0"> <TextBlock HorizontalAlignment="Center" name="txtblkUpdateDescription" Text="Application Update!" VerticalAlignment="Center" Foreground="#FFEF0FDD" FontSize="20"/> </GrID> <cmj:Resizebutton GrID.Row="2" HorizontalAlignment="Right" VerticalAlignment="Bottom" margin="0,0"/> </GrID></UserControl>
下面是安装和运行效果:
四、OOB应用升级上面的OOB应用看起来跟在Web中运行没有两样,又可以以类似于B/S的方式运行,但是大家都知道B/S有一个很多的弊端就是升级问题,那么OOB应用如何升级呢?总不能每次运行程序先删除再安装一次吧?事实上OOB模式下升级工作很简单,只要在程序需要升级时修改AssemblyVersion版本(在项目的AssemblyInfo.cs文件中),然后在程序启动时调用Application.Current.CheckAndDownloadUpdateAsync()方法就能完成更新工作,这里将更新 *** 作写到前面OOBInstall类中。为了便于观看效果,在loaded事件中添加更新 *** 作,接着在浏览器中运行并将之前安装的程序删除重新安装。然后对Main.Xaml做稍许改变(在其中添加一个TextBlock),修改版本信息为,1.0.0.1:
OOBInstall添加更新方法后:
using System;using System.Net;using System.windows;using System.windows.Controls;using System.windows.documents;using System.windows.Ink;using System.windows.input;using System.windows.Media;using System.windows.Media.Animation;using System.windows.Shapes;using System.Net.networkinformation;namespace Cmj.MyWeb.MySilverlight.SiverlightOOB{ public class OOBInstall { public bool IsInstalled() { if (Application.Current.InstallState == InstallState.Installed) { return true; } else { return false; } } /// <summary> /// 程序安装 /// </summary> public voID Install() { if (!Application.Current.IsRunningOutOfbrowser) { if (Application.Current.InstallState != InstallState.Installed) { Application.Current.Install(); } else { MessageBox.Show("程序已安装!",e); } } /// <summary> /// 程序更新(如果需要更细你可以通过修改程序Assembly Version) /// </summary> public voID Update() { //网络改变时事件 NetworkChange.NetworkAddressChanged += new NetworkAddressChangedEventHandler(NetworkChange_NetworkAddressChanged); //判断程序是否在oob下运行并且网络可用 if (Application.Current.IsRunningOutOfbrowser && NetworkInterface.GetIsNetworkAvailable()) { Application.Current.CheckAndDownloadUpdateCompleted += new CheckAndDownloadUpdateCompletedEventHandler(Current_CheckAndDownloadUpdateCompleted); Application.Current.CheckAndDownloadUpdateAsync(); } } voID NetworkChange_NetworkAddressChanged(object sender,EventArgs e) { Console.Writeline("网络发生改变,当前网络状态:{0}",NetworkInterface.GetIsNetworkAvailable().ToString()); } voID Current_CheckAndDownloadUpdateCompleted(object sender,CheckAndDownloadUpdateCompletedEventArgs e) { if (e.UpdateAvailable) { MessageBox.Show("程序已更新到最新版本,请重新启动!",MessageBoxbutton.OK); } else { if (e.Error != null) { MessageBox.Show("程序更新失败,错误信息如下:"+Environment.Newline+e.Error.Message,MessageBoxbutton.OK); } } } } public class InstallStateArgs:EventArgs { public InstallState State { get { return Application.Current.InstallState; } } }}
在MainPage后台代码中调用:
using System;using System.Collections.Generic;using System.linq;using System.Net;using System.windows;using System.windows.Controls;using System.windows.documents;using System.windows.input;using System.windows.Media;using System.windows.Media.Animation;using System.windows.Shapes;using Cmj.MyWeb.MySilverlight.SiverlightOOB;namespace SilverlightApplicationOOB{ public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); } private voID LayoutRoot_Loaded(object sender,RoutedEventArgs e) { } private voID UserControl_Loaded(object sender,RoutedEventArgs e) { OOBInstall oob = new OOBInstall(); oob.Update(); } }}
重新编译程序,再启动程序,程序会自动更新,然后提示更细成功:
接着重启应用,会发现程序更新后的效果:
OK,今天就到这里吧!程序下载
本作品采用知识共享署名 2.5 中国大陆许可协议进行许可,欢迎转载,演绎或用于商业目的。但转载请注明来自崔江涛(KenshinCui),并包含相关链接。 |
以上是内存溢出为你收集整理的Silverlight之out of Browser模式全部内容,希望文章能够帮你解决Silverlight之out of Browser模式所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)