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

Silverlight2 Lightbox

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.18/5 (7投票s)

2008 年 4 月 28 日

Ms-PL

3分钟阅读

viewsIcon

54376

downloadIcon

602

一个 Silverlight2 lightbox 控件。

引言

TeamLive(我最近一直在做的项目)在许多地方混合了 ASP.NET、Ajax 和 Silverlight,我很有兴趣看看我能将 HTML/Silverlight 的混合推到多远——lightbox 似乎是我实验的一个很好的组件。

对于那些想知道的人,Lightbox 是一种效果,它会淡化背景中的页面,以在前景中显示新内容。

本文并非旨在成为 Silverlight 教程。 如果您是这项技术的新手,那么我建议在使用此代码之前阅读一些初学者教程。

背景

TeamLive 在许多地方混合了 ASP.NET、Ajax 和 Silverlight。 例如,在多文件上传期间,我们调整 OBJECT 的样式,使其具有更多的屏幕空间来显示进度条。

image

我一直在为 TeamLive 的下一个迭代版本开发的控件之一是一个 lightbox,以帮助用户浏览他们的图像网格。

下面列出了 lightbox 的一些要求

  • 仅在需要时加载大图(duh!)
  • 小 xap(我们过去使用的 js lightboxes 需要大量的 js 和/或关联的图像) - 这个 xap 只有 8K
  • 每个页面只有一个 Silverlight lightbox 对象(我们不希望创建很多对象)
  • 易于使用(在页面上放置一个 xap 并调用一些 js)
  • 当 Silverlight 2 不存在时,干净地降级

演示

如果您安装了 Silverlight 2,请访问 http://www.devprocess.com 并单击其中一张图片...

后退?

我希望你看到类似这样的东西

image

如果您只是得到一个丑陋的 window.open,那么您没有 Silverlight 2。

Using the Code

首先,是 PageBlanket Silverlight 类。 一个简单的类,可用于通过覆盖来禁用页面。

模态弹出窗口覆盖使用类似的技术(请参阅 AjaxControlToolkit 上的 ModalPopuphttp://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 日:提交文章
© . All rights reserved.