Silverlight 2 如何接收滑鼠滾輪訊息

註: 這裡的範例程式碼是針對 Silverlight 2 Beta1, 在 beta2 中, MultiScaleImage 的 Source 的型態有些改變。

在 Deep Zoom 的應用中, 常常會用滑鼠滾輪來作 Zoom In/ Zoom Out 的動作, 但是 Silverlight 2 Beta1 的 .NET 事件裡並沒有滑鼠滑輪的事件, 必需藉用瀏覽器事件來呼叫滾輪訊息。此外, 要特別注意的是, 滑鼠滾輪雖然方便, 但是並不是所有的作業系統都支援滑鼠滾輪, 也要可能有的使用者的滑鼠根本缺少滾輪, 所以我們在設計滾輪應用的同時, 務必要設計無法使用滾輪時的替代方案。(請參考清明上河圖的設計https://learnet.npm.gov.tw/silverlight/)

範例程式如下, 由於 IE, firefox, Safari 的事件模型不同, 所以要特別注意跨瀏覽器支援的部份, 範例程式碼測試過此三種瀏覽器:

Page.xaml

<UserControl x:Class="SilverlightApplication3.Page"
    xmlns="https://schemas.microsoft.com/client/2007"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    >

    <Grid x:Name="LayoutRoot" Background="White">
        <MultiScaleImage x:Name="dz"
            Source="deepzoomtest1/info.bin" UseSprings="False"
                         MouseLeftButtonDown="MultiScaleImage_MouseLeftButtonDown"
                         MouseMove="MultiScaleImage_MouseMove"
                         MouseLeftButtonUp="MultiScaleImage_MouseLeftButtonUp"
                         />
    </Grid>
</UserControl>

Page.xaml.cs

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;

namespace SilverlightApplication3
{
    [ScriptableType]
    public partial class Page : UserControl
    {
        public Page() {
            InitializeComponent();
            HtmlPage.RegisterScriptableObject("MySilverlightObject", this);
}

        bool dragging = false;
        Point dragOffset;
        Point currentPosition;

        private void MultiScaleImage_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
            dragging = true;
            dragOffset = e.GetPosition(this);
            currentPosition = dz.ViewportOrigin;
        }

        private void MultiScaleImage_MouseMove(object sender, MouseEventArgs e) {
            if (dragging) {
                Point newOrigin = new Point();
                newOrigin.X = currentPosition.X -
                    (((e.GetPosition(dz).X - dragOffset.X)
                    / dz.ActualWidth) * dz.ViewportWidth);
                newOrigin.Y = currentPosition.Y -
                    (((e.GetPosition(dz).Y - dragOffset.Y)
                    / dz.ActualHeight) * dz.ViewportWidth);
                dz.ViewportOrigin = newOrigin;
            }
        }

        private void MultiScaleImage_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) {
            dragging = false;
        }

        [ScriptableMember]
public void dz_MouseWheel(double x, double y, int delta) {
double dZoomFactor = 1.25;
if (delta < 0)
dZoomFactor = 1 / 1.25;
Point pz = dz.ElementToLogicalPoint(new Point(x, y));
dz.ZoomAboutLogicalPoint(dZoomFactor, pz.X, pz.Y);
}

    }
}

TestPage.html

<body onload="handleLoad()">
    <div id='errorLocation' style="font-size: small;color: Gray;"></div>
    <div id="silverlightControlHost">
        <object id="slHost" data="data:application/x-silverlight," type="application/x-silverlight-2-b1" width="100%" height="100%">
            <param name="source" value="ClientBin/SilverlightApplication3.xap"/>
            <param name="onerror" value="onSilverlightError" />
            <param name="background" value="white" />
            <a href="https://go.microsoft.com/fwlink/?LinkID=108182" style="text-decoration: none;">
                 <img src="https://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/>
            </a>
        </object>
        <iframe style='visibility:hidden;height:0;width:0;border:0px'></iframe>
    </div>
    <script type="text/javascript" language="javascript">

    function handleLoad()
{
window.onmousewheel = document.onmousewheel = onMouseWheel;
if (window.addEventListener) // for firefox
window.addEventListener('DOMMouseScroll', onMouseWheel, false);
}

    function onMouseWheel(event)
{
if(event === undefined) // for IE
event = window.event;

        var delta = 0;
var x = (event.clientX);
var y = (event.clientY);
var slPlugin = document.getElementById("slHost");
if (event.wheelDelta !== undefined) {
delta = event.wheelDelta;
slPlugin.content.MySilverlightObject.dz_MouseWheel(x, y ,delta);
} else if (event.detail) { // for firefox
delta = -event.detail;
x /= 15;
y /= 15;
slPlugin.content.MySilverlightObject.dz_MouseWheel(x, y ,delta);
}
}

    </script>
</body>