Silverlight的弹出窗口展示 -电脑资料

电脑资料 时间:2019-01-01 我要投稿
【www.unjs.com - 电脑资料】

背景

年后来到公司实习,第一个星期没有项目,也就无所事是,此时有一位前辈和我说,他们有一个系统 是基于Silverlight研发的,而其中使用的弹出窗口存在着不少的问题,因此如果可以的话,要我做出一 个弹出窗口的功能,其子元素可以是自定义的任何控件,

Silverlight的弹出窗口展示

我很高兴进入公司才几天就能有这样的任务,每一次我去不同的公司实习,总是能在很短的时间内被 “委以重任(当然更多的是我自己在自恋)”去进行可利用的基础设施的研发,非常感谢从大二开始都一 直如此信任和看得我的各家公司,我想只有在这样的环境中才可以全力以赴……

总之接下此任务的情况是这样的,那么至此我对Silverlight到底有多少的知识呢?答案是,零。认识 我的人都知道,我是非常非常没有美工水平的,因此对于几乎所有前台开发的技术都敬而远之,而其中如 此新颖的Silverlight更是令我望而生怯。

但是事已如此,刚进公司也不能说我不会做,于是就硬着头皮上了,最终的结果是这样的:

首先用半天的时间基本撑握了Silverlight的模型,包括了解了Xaml的语法如DependencyProperty, AttachedProeprty等,基本熟悉了相关的API,至于控件树之类的理念,Winform和Webform也是基本相同 的模型,因此熟悉起来也相对较快

随后用半天的时间,折腾出了一个弹出窗口的原型,看起来确实相当地舒服,弹出一个窗口再关闭, 弹出两个窗口再相继关闭,并没有出现特别大的问题

然后,5分钟的时间内,发现这东西并不完美,存在着不少的问题,于是从架构上完全推倒了前一次的 作品,很明显我的实现是基于一个错误的设计,也因此需要将整个模型进行重新的设计并进行再一次的实 现

经过再半天的努力,终于有了一个较为理想化的设计,并完成了这个版本的实现

我们的选择

对于弹出窗口这样的功能,我们在Silverlight中是有多种选择的,在介绍我的作品之前,我们先来看 一下各种选择的优点和缺点

选择1:MessageBox

确实Silverlight中是有一个MesasgeBox的,和Winform中的一样,调用MessageBox.Show即可,但其也 存在着不少问题,当然在这之前我们要先向好的一方面看

优点:MessageBox是同步的,即Show方法调用后可以直接取得返回值,同步编程在简单性上相比异步 编程有着非常大的优势,因此确实可以作为一个好的选择

缺点:知道为什么各JS框架都要出个MessageBox么,就是因为alert这东西实在太难看了,而现在我们 面对着更为绚丽的Silverlight应用,在赏心悦目地享受着的同时,难道要时不时看到一个和alert窗口一 模一样的家伙弹出又消失?

选择2:Popup

Popup是Silverlight基础类库提供的一个控件,可以直接完成弹出的功能

优点:操作简单,可以用Xaml表述,封装了弹出的功能,样式可自定义,作为官方的解决方案甚为强 大

缺点:据前辈说,Popup中包含有DataGrid之类的复杂控件的时候,会有Bug出现,这也是需要我去完 全做一个弹出窗口出来的主要原因……

我的作品—PopupBox

我没有办法称之为MessageBox,因为基础类库中有这东西

我也没办法称之为Popup,因为基础类库中也有这东西

我可不想自己的作品在出现之初就与基础类库有着冲突,要求调用者必须使用全局命名空间引用,更 不想借用官方的名字给人产生混淆的感觉

作为一个作品的展示,先来看看这东西是怎么使用的。事实上这并不是一个控件,而是一个类,因此 你不能使用Xaml声明他,作出这种决定的原因,一是我对Xaml只是掌握,并不熟悉,因此如果要做到使用 Xaml进行声明,可能至今都看不到这家伙的影子,其次是因为弹出窗口往往是通过编程来动态确定其内容 并控制是否弹出的,因此将之作为一个类来使用也不会产生太大的麻烦

为了使用我们的弹出窗口,首先需要获取一个称为PopupService的对象,其掌管着一切弹出之物,你 不能显式地通过new来构造一个PopupService,而必须通过工厂方式获取这个对象

PopupService service = PopupService.GetServiceFor(LayoutRoot);

随后,我们可以使用多种重载,从PopupService中通过调用GetBoxPage来获取弹出窗口的实例,其第 一个参数是显示在弹出窗口中的控件,类型为FrameworkElement,第二个参数为窗口的标题,后面的参数 控制着诸如是否可以拖动,是否显示关闭图标等功能,调用如下

BoxPage box = service.GetBoxPage(
  new MyControl(), //显示的控件
   Title.Text, //标题
  true, //是否可以拖动
  true //是否显示关闭图标
);

你可以给BoxPage加上出现和消失时的特效,现有支持的特效有淡入、缩放以及无特效,当然从设计上 可以非常轻松地对其进行扩展

box.Effect = Effect.Fade(box);

BoxPage拥有ShowComplete和CloseComplete事件,你可以通过注册这些事件来做一些操作

box.ShowComplete += new EventHandler(Box_ShowComplete);
box.CloseComplete += new EventHandler(Box_CloseComplete);

最后调用Show方法弹出窗口,当然也可以调用ShowAsModal方法来弹出一个模式窗口,所谓模式窗口就 是在弹出后会遮住下面所有的控件

box.Show();
box.ShowAsModal();

如果你觉得这样的使用还算简单的话,那么我想我已经成功了一半,当然我们还有另一个控件,你可 以通过调用PopupService的GetMessagePage方法来获取一个消息对话框,这是一个只用来显示消息的不可 以自定义控件作为内容的简单的对话框,在此放上两张图先展示一下效果

在展示以前,我还是想再三声明,我的美工不是一般地差,因此对话框的样式极为难看,请给我时间 去改进样式,谢谢……

左边的是弹出窗口,右边的是消息窗口

这个版本相比上一个版本的改进

当然上一个版本大家是没有见过的,也永远不会见到,但作为对自己的负责,我还是记录一下这个版 本的改进,并且在此之间应当也能略窥此弹出窗口的功能

1.解决多个弹出窗口时遮罩层重复问题,现在多个弹出窗口将共用一个遮罩层

2.解决多个弹出窗口中有一个窗口为模式对话框的情况下,关闭此模式对话框将不会取消模式遮罩层 的问题

3.解决多个弹出窗口的情况下,点击后台窗口将其置于最上层的问题

后续版本将要出现的改进

也许是下一个版本,也许是下n个版本,但是这些改进已经列入了计划,总有一天他们会得到实现

1.多国语言化,主要是按钮的文字

2.提供更多的样式自定义功能

3.优化PopupService的存储,将已经无用的PopupService(即不再管理任何弹出窗)及时从缓存中清 除

4.BoxPage加上Border

5.当前窗口弹出均在遮罩层的中间,改进为可以指定窗口弹出时相对遮罩层的位置

6.如果弹出窗口的位置已经有其他窗口的话,将窗口进行一定量的偏移以保证不会完全挡住原有窗口

7.弹出窗口在拖动的时候可以移出其遮罩层的范围,最好可以控制遮罩层的大小且不允许弹出窗口随 意移动,这样可以将弹出窗口的可移动范围控制在一个区域之内

已知的Bug

当然我只是一只菜鸟,出来的东西必定有着问题,在此是至今发现的问题,也希望大家多多提供 Bug

1.当在BoxPage中加载图片时,使用相对路径将造成读取类库的相对路径的图片,产生图片读取错误, 不知如何才能设置为去读取当前运行项目的相对路径

2.MessagePage和BoxPage中依旧存在部分相似、相同代码,无法完全抽象分离,需要考虑优化设计

3.MessagePage中的内容为一定数量并且没有空格的英文字符串时,会产生最后一个字符换行的问题

4.使用渐隐特效时,因为窗口消失有时间,所以可以多次点击MessagePage上的不同按钮,但结果以最 后一次点击的按钮为准,应当修正为后续按钮的点击都无效

5.无数未知的问题和BUG……

设计及实现的介绍

写到这里的时候我突然发现自己有点累了,虽然这是最重要的内容,但是老妈难得来上海看我,现在 正在旁边,实在没有什么心情继续,因此请允许我将这“精彩”的重头戏留到下一篇

源码分享

以下是本作品的源码地址,对于没有Silverlight开发环境的同学,就不要指望去打开项目了,但是 SilverlightApplication1\debug\bin\TestPage.htm依旧是可以运行的,相信你已经安装了Silverlight Runtime,当然没有安装你也会被微软要求安装的~~

这里是展示页面的一个截图

再次声明,我的美工非常差,因此界面非常简单,我想点一下按钮这事大家都会用,所以我就不对这 个界面多作解释了

本文配套源码

最新文章