Blend to ASPX

in

ให้ตายสิไมโครซอฟท์ ออก Microsoft Expression Blend มาให้ใช้ แต่กลับไม่มีวิธีง่ายๆในการฝังไฟล์ Silverlight ลงใน ASP.NET !!!

เรื่องเริ่มต้นที่ว่าตอนหัดใช้ Silverlight ก็ต้องมานั่งแกะเองทีละขั้น ตอนนั้นก็คิดว่า ของใหม่เครื่องมือยังห่วยอยู่ ใช้งานยาก ก็น่าให้อภัย แต่ก็คิดว่า ซักวันมันต้องมีคนมาถามแน่ๆเลยว่าจะเอา XAML ไปใช้ยังไง

วันนี้เพื่อนมาถาม

นาย ม. says:
วีน ถามหน่อย สมมุติทำของใน blend เส็ดแล้ว จะใส่เข้าไปใน aspx ยังไง

โอ้…พระเจ้า ไมโครซอฟท์ทำสิ่งที่เราฝันไว้ได้จริงๆด้วย

อันนี้จะทำเฉพาะ 1.0 ไว้ละกันนะ

เริ่มต้นด้วยการเปิด Blend แล้วสร้าง Project เป็น Silverlight 1.0 Site อันนี้ขอใช้ Blend Preview 2.5 ละกัน

Project

จากนั้นสร้าง XAML ขึ้นมาให้เรียบร้อย

Blend2

แล้วลองเปิดเว็บไซต์ด้วย Visual Studio ซะ แล้วลองเปิดไฟล์ Default.html มาดู จะเห็นเป็นแบบนี้

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- saved from url=(0014)about:internet -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>SilverlightSite4</title>

    <script type="text/javascript" src="Silverlight.js"></script>
    <script type="text/javascript" src="Page.xaml.js"></script>
    <style type="text/css">
        #silverlightControlHost {
            height: 480px;
            width: 640px;
        }
        #errorLocation {
            font-size: small;
            color: Gray;
        }
    </style>
    <script type="text/javascript">
        function createSilverlight()
        {
            var scene = new SilverlightSite4.Page();
            Silverlight.createObjectEx({
                source: "Page.xaml",
                parentElement: document.getElementById("silverlightControlHost"),
                id: "SilverlightControl",
                properties: {
                    width: "100%",
                    height: "100%",
                    version: "1.0"
                },
                events: {
                    onLoad: Silverlight.createDelegate(scene, scene.handleLoad),
                    onError: function(sender, args) {
                        var errorDiv = document.getElementById("errorLocation");
                        if (errorDiv != null) {
                            var errorText = args.errorType + "- " + args.errorMessage;

                            if (args.ErrorType == "ParserError") {
                                errorText += "<br>File: " + args.xamlFile;
                                errorText += ", line " + args.lineNumber;
                                errorText += " character " + args.charPosition;
                            }
                            else if (args.ErrorType == "RuntimeError") {
                                errorText += "<br>line " + args.lineNumber;
                                errorText += " character " +  args.charPosition;
                            }
                            errorDiv.innerHTML = errorText;
                        }   
                    }
                }
            });
        }


        if (!window.Silverlight) 
            Silverlight = {};

        Silverlight.createDelegate = function(instance, method) {
            return function() {
                return method.apply(instance, arguments);
            }
        }
    </script>
</head>

<body>
    <div id="silverlightControlHost">
        <script type="text/javascript">
            createSilverlight();
        </script>
    </div>

    <!-- Runtime errors from Silverlight will be displayed here.
    This will contain debugging information and should be removed or hidden when debugging is completed -->
    <div id='errorLocation'></div>
</body>
</html>

เราจะลองมาชำแหละทีละส่วนดูว่า แต่ละอันมันคืออะไร

เริ่มจาก



SilverlightSite4

อันนี้ไม่มีอะไร แค่เป็นหัวของ HTML ไม่ต้องสนใจ

    <script type="text/javascript" src="Silverlight.js"></script>
    <script type="text/javascript" src="Page.xaml.js"></script>

สำหรับสองบรรทัดนี้ บรรทัดแรกจะ้เป็นการเพิ่ม reference ของ silverlight.js ที่เป็นไฟล์ที่เก็บโค้ดที่ใช้ตรวจสอบว่ามีการติดตั้ง Silverlight ไว้หรือยัง และประกาศเมธอดช่วยต่างๆเช่น Silverlight.createObjectEx เป็นต้น
สำหรับบรรทัดที่สองเป็นการโหลดไฟล์ Page.xaml.js ซึ่งเป็นไฟล์ที่เก็บสคริปต์ที่ใช้ควบคุม ตัว XAML ของเรา

    <style type="text/css">
        #silverlightControlHost {
            height: 480px;
            width: 640px;
        }
        #errorLocation {
            font-size: small;
            color: Gray;
        }
    </style>

ต่อมา ก็เป็น css ที่บอกว่า ให้ element ที่มี id silverlightControlHost มีขนาดกว้างยาวเป็น 640*480 พิกเซล

function createSilverlight()
{
    var scene = new SilverlightSite4.Page();
    Silverlight.createObjectEx({
        source: "Page.xaml",
        parentElement: document.getElementById("silverlightControlHost"),
        id: "SilverlightControl",
        properties: {
            width: "100%",
            height: "100%",
            version: "1.0"
        },
        events: {
            onLoad: Silverlight.createDelegate(scene, scene.handleLoad),
            onError: function(sender, args) {
                var errorDiv = document.getElementById("errorLocation");
                if (errorDiv != null) {
                    var errorText = args.errorType + "- " + args.errorMessage;

                    if (args.ErrorType == "ParserError") {
                        errorText += "<br>File: " + args.xamlFile;
                        errorText += ", line " + args.lineNumber;
                        errorText += " character " + args.charPosition;
                    }
                    else if (args.ErrorType == "RuntimeError") {
                        errorText += "<br>line " + args.lineNumber;
                        errorText += " character " +  args.charPosition;
                    }
                    errorDiv.innerHTML = errorText;
                }   
            }
        }
    });
}

ฟังก์ชันต่อมา ยาวนิดนึง คือฟังก์ชัน createSilverlight() ฟังก์ชันนี้แหละที่เป็นหัวใจสำคัญในการเรียกใช้ Silverlight โดยตอนแรกก็จะสร้าง object ของ Silverlight4.Page ขึ้นมา โดยคลาสนี้จะอยู่ในไฟล์ Page.Xaml.js

หลังจากนั้นก็จะโหลด xaml ด้วยคำสั่ง Silverlight.createObjectEx โดยพารามิเตอร์ที่ใส่เข้าไปจะเป็น hash ที่มีพารามิเตอร์ดังนี้

  • source อันนี้ระบุว่าจะให้โหลดไฟล์ขึ้นมา
  • parentElement ระบุเพื่อบอกว่าให้ใส่ลงไปใน element ไหน
  • id ตั้งชื่อว่าอะไร
  • properties อันนี้กำหนดความกว้าง สูง กำหนดเป็นเปอร์เซนต์ได้ หรือจะกำหนดเป็นพิกเซลก็ได้ จริงๆแล้วก็ตั้งตรงนี้เป็น 100 เปอร์เซนต์ แล้วก็ไปกำหนดตรง CSS ข้างบนเอาดีกว่า
  • events สำหรับอันนี้จะเป็นผูก event เข้ากับ method ต่างๆ ซึ่งในที่นี้ก็คือจะไปผูกกับ method handleLoad

        if (!window.Silverlight) 
            Silverlight = {};
    
        Silverlight.createDelegate = function(instance, method) {
            return function() {
                return method.apply(instance, arguments);
            }
        }
    

ตรงนี้เป็นการสร้าง class Silverlight ขึ้นมาพร้อม static method ชื่อ createDelegate เพื่อจะได้เอาใช้ต่อ

    <div id="silverlightControlHost">
        <script type="text/javascript">
            createSilverlight();
        </script>
    </div>

ตรงนี้จะเป็น element ที่จะเป็นที่วาง Silverlight ลงไป สังเกตว่าจะไปเรียกฟังก์ชัน createSilverlight ข้างบนด้วย

พอเรารู้แบบนี้ เราก็น่าจะพอเดาได้ว่าจะต้องเอาอะไรไปแปะตรงไหนแล้วใช่ไหม
หลักๆที่ต้องเอาไปก็คือ ส่วน script, css, แล้วก็ จุดวาง

ทีนี้ลองสร้าง aspx ขึ้นมาอันนึง

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>

    </div>
    </form>
</body>
</html>

แล้วก็ทำแบบเมื่้อกี้ สำคัญสุดคือ script เอาไปไว้ใน tag head แบบอันเก่าก็ได้ หรือถ้าใครใช้ ASP.NET Ajax ก็เอาไปไว้ใน ScriptManager ก็ได้ไม่ว่ากัน

<form id="form1" runat="server">
<div>
    <asp:ScriptManager ID="ScriptManager1" runat="server">
    <Scripts>
        <asp:ScriptReference Path="~/Silverlight.js" />
        <asp:ScriptReference Path="~/Page.xaml.js" />
    </Scripts>
    </asp:ScriptManager>
</div>
</form>

สำหรับใครที่ทำแบบมีหลายๆไฟล์สคริปต์ต้องใส่ให้ครบทุกไฟล์ จุดนี้จะต่างจาก xaml ที่เราเอาไปไว้ใน zip file แล้วใช้ downloader ดึงมาทีหลังได้

ทีนี้ก็เพิ่มฟังก์ชัน createSilverlight , css แล้วก็เพิ่มจุดวางเข้าไป

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>

<%@ Register Assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
    Namespace="System.Web.UI" TagPrefix="asp" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Untitled Page</title>
    <script type="text/javascript">
        function createSilverlight()
        {
            var scene = new SilverlightSite4.Page();
            Silverlight.createObjectEx({
                source: "Page.xaml",
                parentElement: document.getElementById("silverlightControlHost"),
                id: "SilverlightControl",
                properties: {
                    width: "100%",
                    height: "100%",
                    version: "1.0"
                },
                events: {
                    onLoad: Silverlight.createDelegate(scene, scene.handleLoad),
                    onError: function(sender, args) {
                        var errorDiv = document.getElementById("errorLocation");
                        if (errorDiv != null) {
                            var errorText = args.errorType + "- " + args.errorMessage;

                            if (args.ErrorType == "ParserError") {
                                errorText += "<br>File: " + args.xamlFile;
                                errorText += ", line " + args.lineNumber;
                                errorText += " character " + args.charPosition;
                            }
                            else if (args.ErrorType == "RuntimeError") {
                                errorText += "<br>line " + args.lineNumber;
                                errorText += " character " +  args.charPosition;
                            }
                            errorDiv.innerHTML = errorText;
                        }   
                    }
                }
            });
        }


        if (!window.Silverlight) 
            Silverlight = {};

        Silverlight.createDelegate = function(instance, method) {
            return function() {
                return method.apply(instance, arguments);
            }
        }
    </script>
    <style type="text/css">
        #silverlightControlHost {
            height: 480px;
            width: 640px;
        }
        #errorLocation {
            font-size: small;
            color: Gray;
        }
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server">
    <Scripts>
        <asp:ScriptReference Path="~/Silverlight.js" />
        <asp:ScriptReference Path="~/Page.xaml.js" />
    </Scripts>
    </asp:ScriptManager>
    <div id="silverlightControlHost">
        <script type="text/javascript">
            createSilverlight();
        </script>
    </div>    
    </form>
</body>
</html>

ลองเปิดดูก็จะได้ผลลัพธ์เหมือนรันใน HTML แล้วล่ะ

SilverlightResult

แต่แบบนี้มันไม่เท่ ถ้าใครใช้ ASP.NET 3.5 แล้วมันจะมี Silverlight Control เพิ่มเข้ามา แต่จากเท่าที่ลองเล่นดูพบว่า ถ้าใช้กับ Silverlight 1.0 มันใช้ยากยิ่งนัก แถมยังไปใช้เทคนิคของ ASP.NET AJAX ที่ไม่ค่อยน่าอภิรมย์ซักเท่าใดนัก แต่สำหรับคนที่ใช้ Silverlight 2.0 ดูท่าว่าจะทำให้ชีวิตสบายขึ้นอย่างมากมาย

ลองดูแล้วกัน ได้ผลยังไงวานบอก

ชอบให้พี่เขียนแนวๆนี้มากมาย เ

ชอบให้พี่เขียนแนวๆนี้มากมาย

เป็นกำลังใจให้ครับ

จุ๊บๆ

It’s really cool, man!

It’s really cool, man!

Post new comment

The content of this field is kept private and will not be shown publicly.