Silverlight2 Lightbox
一个 Silverlight2 lightbox 控件。

引言
TeamLive(我最近一直在做的项目)在许多地方混合了 ASP.NET、Ajax 和 Silverlight,我很有兴趣看看我能将 HTML/Silverlight 的混合推到多远——lightbox 似乎是我实验的一个很好的组件。
对于那些想知道的人,Lightbox 是一种效果,它会淡化背景中的页面,以在前景中显示新内容。
本文并非旨在成为 Silverlight 教程。 如果您是这项技术的新手,那么我建议在使用此代码之前阅读一些初学者教程。
背景
TeamLive 在许多地方混合了 ASP.NET、Ajax 和 Silverlight。 例如,在多文件上传期间,我们调整 OBJECT 的样式,使其具有更多的屏幕空间来显示进度条。
我一直在为 TeamLive 的下一个迭代版本开发的控件之一是一个 lightbox,以帮助用户浏览他们的图像网格。
下面列出了 lightbox 的一些要求
- 仅在需要时加载大图(duh!)
- 小 xap(我们过去使用的 js lightboxes 需要大量的 js 和/或关联的图像) - 这个 xap 只有 8K
- 每个页面只有一个 Silverlight lightbox 对象(我们不希望创建很多对象)
- 易于使用(在页面上放置一个 xap 并调用一些 js)
- 当 Silverlight 2 不存在时,干净地降级
演示
如果您安装了 Silverlight 2,请访问 http://www.devprocess.com 并单击其中一张图片...
后退?
我希望你看到类似这样的东西
如果您只是得到一个丑陋的 window.open
,那么您没有 Silverlight 2。
Using the Code
首先,是 PageBlanket
Silverlight 类。 一个简单的类,可用于通过覆盖来禁用页面。
模态弹出窗口覆盖使用类似的技术(请参阅 AjaxControlToolkit 上的 ModalPopup
: http://www.asp.net/AJAX/AjaxControlToolkit/Samples/ModalPopup/ModalPopup.aspx)
/// <summary>
/// PageBlanket covers a page with a partially transparent div
/// to prevent users interacting with the page - can be used to simulate a modal
/// dialog
/// </summary>
public class PageBlanket
{
HtmlElement _blanket = null;
/// <summary>
/// Lazy initialization on first call
/// </summary>
private void Initialize()
{
if (_blanket == null)
{
//create a div that will take up the whole page and
//cover the content underneath
_blanket = HtmlPage.Document.CreateElement("div");
HtmlPage.Document.Body.AppendChild(_blanket);
_blanket.SetStyleAttribute("position", "fixed");
_blanket.SetStyleAttribute("top", "0px");
_blanket.SetStyleAttribute("left", "0px");
_blanket.SetStyleAttribute("height", "100%");
_blanket.SetStyleAttribute("width", "100%");
_blanket.SetStyleAttribute("backgroundColor", "#808080");
_blanket.SetStyleAttribute("filter", "alpha(opacity=50)");
_blanket.SetStyleAttribute("opacity", "0.5");
_blanket.SetStyleAttribute("z-index", "3");
_blanket.SetStyleAttribute("display", "none");
}
}
/// <summary>
/// Show the blanket and cover the page
/// </summary>
public void Show()
{
//just in case not init'ed
Initialize();
//clear display attribute to show the blanket
_blanket.SetStyleAttribute("display", "");
}
/// <summary>
/// Hide the blanket again
/// </summary>
public void Hide()
{
//hide the blanket
_blanket.SetStyleAttribute("display", "none");
}
}
Page blanket 创建一个 div
,设置样式,将其插入页面,并切换显示样式以显示/隐藏 div
。 这有效地禁用了页面,而我们正在进行 Silverlight 操作。
动态显示/隐藏 Silverlight 控件变得更加困难。
如果您开始移动控件、更改 zIndex
、动态更改显示样式,Firefox 会感到不安。
我在 Internet Explorer 7 中获得了可用的代码,并在 Firefox 中获得了“尝试获取脚本插件对象上不支持的属性!”错误。
我发现的解决方案(适用于 Internet Explorer 7、Firefox2 和 Safari(尚未在其他任何设备上进行测试))是设置一个小的宽度和高度(是的,是的 - 我知道)。 我确保在开始时设置对象的样式(在 C# 中动态更改位置和 zIndex
会搞砸 scriptableobject
)。
Lightbox 代码
请注意,它将 lightbox 定位在屏幕中央。 最初,代码将 lightbox 定位在启动它的项目上方 - 但它看起来总是不太正确,所以我尝试将 lightbox 定位在中心。 我不确定它在中心是否更好 - 所以我正在等待灵感。
using System;
using System.Collections.Generic;
using System.Linq;
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 System.Windows.Browser;
using System.Windows.Media.Imaging;
namespace dpLightbox
{
[ScriptableType]
public partial class Page : UserControl
{
public Page()
{
InitializeComponent();
Loaded += new RoutedEventHandler(Page_Loaded);
//keep the lightbox in the center if page is resized
HtmlPage.Window.AttachEvent("onresize", new EventHandler(Window_Resize));
}
void Window_Resize(object sender, EventArgs e)
{
PositionToCenter();
}
void Page_Loaded(object sender, RoutedEventArgs e)
{
//register for javascript control
HtmlPage.RegisterScriptableObject("LightboxController", this);
//the close button
bClose.MouseEnter += new MouseEventHandler(bClose_MouseEnter);
bClose.MouseLeave += new MouseEventHandler(bClose_MouseLeave);
bClose.MouseLeftButtonUp +=
new MouseButtonEventHandler(bClose_MouseLeftButtonUp);
}
bool closing = false;
/// <summary>
/// Close the lightbox
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void bClose_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
closing = true;
rCloseGlow.Opacity = 0.0;
sbLightbox.Completed += new EventHandler(sbLightbox_Completed);
sbLightbox.AutoReverse = true;
sbLightbox.Stop();
sbLightbox.Begin();
sbLightbox.Seek(new TimeSpan(0, 0, 0, 0, 500));
}
void sbLightbox_Completed(object sender, EventArgs e)
{
if (closing)
{
_blanket.Hide();
Width = 0;
Height = 0;
HtmlPage.Plugin.SetStyleAttribute("width", "1px");
HtmlPage.Plugin.SetStyleAttribute("height", "1px");
}
closing = false;
}
void bClose_MouseLeave(object sender, MouseEventArgs e)
{
rCloseGlow.Opacity = 0.0;
}
void bClose_MouseEnter(object sender, MouseEventArgs e)
{
rCloseGlow.Opacity = 1.0;
}
double paddingTop = 55;
double padding = 25;
PageBlanket _blanket = new PageBlanket();
[ScriptableMember]
public void showLightbox(string imgTitle, string imgSrc,
double imgWidth, double imgHeight)
{
_blanket.Show();
txtTitle.Text = imgTitle;
imgMain.Source = new BitmapImage
(new Uri(imgSrc, UriKind.RelativeOrAbsolute));
imgMain.ImageFailed += new ExceptionRoutedEventHandler(imgMain_ImageFailed);
//setup the lightbox size
double dWidth = imgWidth + (padding * 2);
double dHeight = imgHeight + (padding + paddingTop);
Width = dWidth;
Height = dHeight;
kfWidth.Value = dWidth;
kfHeight.Value = dHeight;
HtmlPage.Plugin.SetStyleAttribute("height", Height.ToString() + "px");
HtmlPage.Plugin.SetStyleAttribute("width", Width.ToString() + "px");
sbLightbox.Stop();
sbLightbox.Seek(new TimeSpan(0));
sbLightbox.AutoReverse = false;
sbLightbox.Begin();
HtmlPage.Plugin.SetStyleAttribute("display", "");
PositionToCenter();
}
void imgMain_ImageFailed(object sender, ExceptionRoutedEventArgs e)
{
//the developer needs to decide what should happen here
//empty lightbox? don't show the lightbox?
}
private void PositionToCenter()
{
Size clientBounds = BrowserHelper.GetClientBounds();
Point ptScrollPos = BrowserHelper.GetScrollPosition();
double dTop = ptScrollPos.Y + ((clientBounds.Height - Height) / 2);
double dLeft = ptScrollPos.X + ((clientBounds.Width - Width) / 2);
HtmlPage.Plugin.SetStyleAttribute("top", dTop.ToString() + "px");
HtmlPage.Plugin.SetStyleAttribute("left", dLeft.ToString() + "px");
}
}
}
使用 Lightbox
在你的 aspx 中
<asp:Silverlight ID="slLb" runat="server"
Source="~/ClientBin/dpLightbox.xap" Version="2.0"
Width="1px" Height="1px" PluginBackground="Transparent" Windowless="true"
style="position:absolute;z-index:4;">
<PluginNotInstalledTemplate></PluginNotInstalledTemplate>
</asp:Silverlight>
当未安装 Silverlight 2 时,PluginNotInstalledTemplate
会消除安装 Silverlight 2 的提示 - 这很好,因为 Lightbox
不是基本功能。
将这段 JavaScript 放在 head 中以简化使用。 这使 Silverlight xap 显示 lightbox 或(shudder)window.open
(如果 Silverlight 2 不存在)。
<script type="text/javascript">
function lightbox(imgTitle,imgSrc,imgWidth,imgHeight)
{
var lbContent=document.getElementById("slLb").Content;
if(lbContent!=null)
{
lbContent.LightboxController.showLightbox
(imgTitle,imgSrc,imgWidth,imgHeight);
}
else
{
window.open(imgSrc,"noSilverlight","menubar=no,
toolbar=no,height="+imgHeight+",width="+imgWidth);
}
}
</script>
显示 lightbox - 要显示 lightbox,请调用上面的函数。
<a href="javascript:lightbox('TeamLive designer',
'http://www.devprocess.com/App_Themes/Default/lb_designer.jpg',600,296);">
<img src="App_Themes/default/designer.jpg" class="photosmall"
width="264" height="130" alt="Screenshot from devProcess TeamLive" />
</a>
TeamLive
您可以随时关注我们的博客上的任何更新(我也会尝试在这里更新): TeamLive Blog。
历史
- 2008 年 4 月 28 日:提交文章