1 Results for 'Scriptable'

  1. 2007.06.25 [Silverlight] 키보드 입력과 마우스 휠 이벤트 지원 (11)
키보드 입력과 마우스 휠 이벤트 지원

현재 실버라이트는 아직은 베타 상태이기도 해서 갖가지 버그도 있고 언어적 지원이 부실한 곳도 있어요. 하지만 언제나 그렇듯 아키텍처 자체에서 불가능한 일이 아니라면 어느 정도 핵hack과 트릭trick이 있게 마련이죠.

사용자 입력 인터페이스의 관점에서 제일 아쉬웠던 건 마우스 이벤트를 이동과 왼쪽 버튼에 한정시킨데다가 플래쉬 최대의 문제점인 오른쪽 버튼 클릭시 강제로 플래쉬 메뉴가 뜨는 것과 같이 덜렁 Silverlight 링크 메뉴 하나 던져준다는 점이었죠.

그 외에도 마우스 휠 이벤트가 아예 고려되어 있지 않고 키보드 입력 지원도 몇몇 키의 지원이 버그로 지원되지 않는 점이 있어요. 특히 방향키의 Down 이벤트가 발생하지 않는 버그는 좀 황당하네요.

이런 기본적인 문제점 들은 아마도 정식 버전이 나오면서 한방에 해결될 가능성이 높지만, 지금 당장 써먹을 필요가 있다면 핵을 쓰는 수밖에요.

Scriptable 지원

이런 문제점들의 해결은 의외로 간단한 편이에요. 실버라잇 컨트롤은 HTML 페이지에 호스팅 되며 사실 실버라잇에서 지원해주는 사용자 입력 이벤트는 HTML 페이지에서 발생되는 이벤트를 핸들링하여 전달해주는 것 뿐이죠.

따라서 HTML 페이지에서 실버라잇 컨트롤에 발생하는 이벤트를 Javascript로 핸들링하여 다시 실버라잇 컨트롤로 던져주는 코드를 작성한다면? 충분히 가능해 보이죠?

그런데 이것을 구현하려면 Javascript와 매니지드 코드와의 연동이 필요해요. 하지만 어떻게?

바로 이러한 종류의 연동을 위해 실버라잇은 Scriptable이라는 방법을 제공하고 있어요.

원래 이 주제는 QuickStarts의 일부로 다룰 예정이었는데 당분간 QuickStarts는 쉬고 있어서 아직 포스팅을 못했어요. 이 부분을 공부해보실 분은 http://silverlight.net/QuickStarts/Dom/ManagedCodeAccess.aspx 이곳을 참고하세요.

간략하게 소개하자면, 코드-비하인드에서 [Scriptable]이란 어트리뷰트를 부여한 public 클래스와 메소드 및 프로퍼티를 애플리케이션 전역의 Scriptable 개체로 등록하고 이것을 Javascript에서 접근할 수 있게 하는 방법이에요. 실버라잇 컨트롤에서 키를 눌렀을 때(KeyDown) 처리를 수행하는 간단한 샘플 코드를 작성해보자면 다음과 같아요.

Scriptable 샘플(KeyDown 이벤트 처리)
1. 코드-비하인드에 [Scriptable] 개체를 작성합니다. (기본적인 Using 구문 생략)
C#
using System.Windows.Browser; // 호스트 브라우저 클래스 지원

[Scriptable]
public class ScriptableSample
{
    [Scriptable]
    public void FireKeyDown(int keyCode)
    {
        // Down된 keyCode를 처리...
    }
}

2. 코드-비하인드에서 작성된 Scriptable 개체의 인스턴스를 생성하고 애플리케이션에 등록합니다. 이 작업은 일반적으로 페이지의 메인 코드에서 수행됩니다.
C#
using System.Windows.Browser; // 호스트 브라우저 클래스 지원

public class Page : Canvas
{
    public void Page_Loaded(object o, EventArgs e)
    {
        // Required to initialize variables
        InitializeComponent();

        ScriptableSample scriptable = new ScriptableSample();    // 생성
        WebApplication.Current.RegisterScriptableObject("ScriptableKey", scriptable);    // 등록
    }
}

3. Javascript로 Scriptable로 등록된 실버라잇 컨트롤의 개체를 획득하고 실버라잇 컨트롤에서 발생하는 이벤트를 핸들링하는 코드를 작성.
Javascript
var silverlightControl = null;
var scriptableObject = null;

// 실버라잇 컨트롤과 Scriptable 개체를 획득
// elementName - 실버라잇 컨트롤을 호스팅하는 엘리먼트의 이름
function LoadScriptable(elementName)
{
    // 실버라잇 컨트롤 바인딩
    silverlightControl = document.getElementById(elementName);

    // KeyDown 이벤트 핸들러 등록
    silverlightControl.onkeydown = HandleKeyDown;

    // 실버라잇 Scriptable 개체 지정, Key는 반드시 매니지드 코드에서 설정한 값을 사용할 것.
    // (setTimeout으로 딜레이를 줘야함)
    var scriptableKey = 'ScriptableKey';
    var scriptableObjectBinding = 'scriptableObject = silverlightControl.Content.' + scriptableKey;
    setTimeout('eval(scriptableObjectBinding);', 1);
}

// KeyDown 이벤트 핸들러
function HandleKeyDown(event)
{
    if (!event) // IE
        event = window.event;
   
    var
keyNum = 0;
    if(window.event) // IE
        keyNum = event.keyCode;
    else if(event.which) // Netscape/Firefox/Opera
        keyNum = event.which;

    if ( scriptableObject != null )
        scriptableObject.FireKeyDown(keyNum);
}

// Scriptable 개체를 로드
LoadScriptable('SilverlightControl');


여하튼, Scriptable을 사용하려면 최소한 HTML 페이지의 이벤트를 핸들링 할 추가적인 Javascript 코드, Scriptable 개체 및 Scriptable 메소드(또는 프로퍼티)를 선언하고 이것을 WebApplication에 등록해야 하는 상당히 귀찮은 작업을 반복해야 하죠.

게다가 Scriptable이 필요한 HTML 페이지 마다 저런 Javascript 코드를 Copy&Paste 한다는 건 너무 너무 너무 너무 너무나도 소모적이고 비효율적인 작업이 될 거에요.

단지 깔끔한 매니지드 코드로 작성된 클래스 하나로 이런 기능들을 한방에 지원할 수 없을까... 고민해보고 답을 얻었습니다.

HTML DOM에 동적으로 Javascript 추가

QuickStarts, HTML DOM의 사용에서 매니지드 코드에서 HTML DOM에 접근하고 제어하는 방법에 대해 소개했었죠. HTML DOM은 W3C에서 표준으로 제정되었기 때문에 어떤 언어라도 같은 기능을 가지고 있음을 확신할 수 있는데요, HTML DOM의 메소드 중에는 DOM에 태그 이름을 통해 새 엘리먼트를 동적으로 추가할 수 있는 AppendChild라는게 있어요.

그럼, Javascript 구문을 <script>태그로 추가하고 이 태그의 Text 내용을 위의 샘플에서 귀찮게 작성한 코드로 설정한다면? 앉아서, 아니 누워서 마음대로 Javascript를 추가하고 제어할 수 있겠죠?

동적으로 Javascript를 추가하는 아주 간단한 예를 들어 보자면...
C#
using System.Windows.Browser; // 호스트 브라우저 클래스 지원

public class Page : Canvas
{
    public void Page_Loaded(object o, EventArgs e)
    {
        // Required to initialize variables
        InitializeComponent();

        // HTML DOM에 Element 추가하기
        HtmlDocument doc = HtmlPage.Document;
        HtmlElement ele = doc.CreateElement("script");
        ele.SetProperty("Text", @"alert('매니지드 코드에서 작성한 스크립트!');");
        doc.DocumentElement.AppendChild(ele);
    }
}

간단하죠?

이 트릭을 이용하면 대부분의 Javascript를 매니지드 코드에서 동적으로 생성하여 붙여 넣을 수 있는 엄청난 가능성이 생겨요.

이번 포스팅에서는 샘플들의 프로젝트를 첨부하지 않았고 대신, 실제로 써먹을 만한 완성된 프로젝트를 첨부했으니 코드를 보고 연구해보시길 바래요. Scriptable은 약간은 복잡하고 어려운 부분이니까 강좌 형식으로 쓰고 싶었는데 지금은 그렇게 하기가 무리가 있네요. :(

프로젝트는 키보드 입력(KeyDown, KeyPress, KeyUp) 및 마우스 휠 이벤트 정보를 출력하는 테스트 페이지에요.

프로젝트 테스트 :
http://gongdo.oranc.co.kr/Silverlight/Samples/ScriptableTester/TestPage.html

ScriptableTester.zip

스크립터블 프로젝트



신고
Posted by gongdo


티스토리 툴바