Sonntag, 25. November 2007

Tastaturereignisse in Silverlight Alpha 1.1

Mich interessiert viel mehr ob und wie man LOB-Applikationen mit Silverlight realisieren kann, als toll designte Multimediale Seiten oder Spiele.
Dabei fällt zuallererst auf, dass dafür keine Eingabe-Controls zur Verfügung stehen (die aber mit der Beta-Version von Silverlight 1.1 geliefert werden sollen).

Für einen Softwareentwickler sollte das kein Problem darstellen.
Ich versuche mich also an einer TextBox für Silverlight.

Bereits mehrfach bin ich auf den Hinweis gestossen, dass Spiele die mit Silverlight realisiert wurden, nicht die Cursurtasten für die Steuerung verwenden da diese kein KeyDown-Event liefern. Nachdem auch eine TextBox intensiv von Tastaturereignissen gebrauch macht ;-) habe ich diesen Aspekt zuerst untersucht.

Es stimmt, Silverlight liefert einige Tastaturereignisse nicht.
Aber es gibt Abhilfe - die fehlenden Ereignisse kann man sich einfach vom Browser liefern lassen.

In CreateSilverlight.js werden die Tastaturereignisse registriert und beim Auftreten an das Silverlight-Plugin weitergereicht:

   1 var sl_Sender;
2 var sl_Plugin;
3 var sl_PluginHost;
4 var sl_Context;
5
6 //contains calls to silverlight.js, example below loads Page.xaml
7 function createSilverlight()
8 {
9 Silverlight.createObjectEx({
10 source: "Page.xaml",
11 parentElement: document.getElementById("SilverlightControlHost"),
12 id: "SilverlightControl",
13 properties: {
14 width: "100%",
15 height: "100%",
16 version: "1.1",
17 enableHtmlAccess: "true"
18 },
19 events: {
20 onError:null,
21 onLoad:sl_OnLoad
22 }
23 });
24
25
26 // Give the keyboard focus to the Silverlight control by default
27 document.body.onload = function() {
28 var silverlightControl = document.getElementById('SilverlightControl');
29
30 if (silverlightControl)
31 silverlightControl.focus();
32 }
33
34
35 //onkeypress doesn't work in IE (7?) if Silverlight has focus
36 document.onkeypress = function(evt) {
37 var charCode = 0;
38
39 evt = (evt) ? evt : ((event) ? event : null);
40
41 if (evt)
42 charCode = evt.charCode; // || evt.keyCode;
43
44 return sl_Plugin.Content.smRootCanvas.DoHostKeyPress(charCode);
45 }
46
47 document.onkeydown = function(evt) {
48 var keyCode = 0;
49
50 evt = (evt) ? evt : ((event) ? event : null);
51
52 if (evt)
53 keyCode = evt.keyCode;
54
55 // returning bool from [Scriptable] doesnt work properly so int is used instead
56 return (sl_Plugin.Content.smRootCanvas.DoHostKeyDown(keyCode) != 0);
57 }
58
59 document.onkeyup = function(evt) {
60 var keyCode = 0;
61
62 evt = (evt) ? evt : ((event) ? event : null);
63
64 if (evt)
65 keyCode = evt.keyCode;
66
67 // returning bool from [Scriptable] doesnt work properly so int is used instead
68 return (sl_Plugin.Content.smRootCanvas.DoHostKeyUp(keyCode) != 0);
69 }
70 }
71
72 function sl_OnLoad(plugin, userContext, sender)
73 {
74 //alert(plugin.id + " : " + userContext + " : " + sender.toString());
75 sl_Sender = sender;
76 sl_Plugin = sender.getHost();
77 sl_PluginHost = plugin;
78 sl_Context = userContext;
79
80 if (plugin)
81 plugin.focus();
82 }

Ein Custom Control in Silverlight kann die Tastaturereignisse empfangen und verarbeiten:

   1 namespace SaveMethod.Silverlight.Controls
2 {
3 [Scriptable]
4 public class SmCanvas : System.Windows.Controls.Canvas
5 {
6 [Scriptable]
7 public int DoHostKeyPress(int keyCode)
8 {
9 System.Diagnostics.Debug.WriteLine(String.Format("HostKeyPress - keyCode: {0}", keyCode));
10
11 // process keyboard events here ...
12
13
14 return Convert.ToInt32(!AbsorbKey(e.HostKey));
15 // AbsorbKey is a custom method (not presented here)
16 // to decide if the event should be handled back to the browser for further processing outside Silverlight
17 // returning 0 disables and 1 enables further event processing
18 }
19
20 [Scriptable]
21 public int DoHostKeyDown(int keyCode)
22 {
23 // process keyboard events here ...
24 }
25
26 [Scriptable]
27 public int DoHostKeyUp(int keyCode)
28 {
29 // process keyboard events here ...
30 }
31 }
32 }

Das Scriptable Attribut für die Klasse und die Methode macht die Methode für JavaScript aufrufbar.

Das "Schlucken" des Ereignisses durch einen Returnwert 0 ist besonders für die Tab-Taste interessant, denn wenn auch der Browser das Ereignis verarbeitet, wird der Cursor in die Adressleiste (IE7) gesetzt. Das ist bei Dateneingabeformularen kaum gewünscht.

In diesem custom Control kann man die empfangenen Tastaturereignisse per C# Events weiteren Controls zum Abonnement anbieten.

  • Ist dieser Beitrag hilfreich?

  • Fehlen Informationen?

  • Kann man das besser, einfacher, kürzer, ... lösen?


Schreibe einen Kommentar um diesen Beitrag noch nützlicher zu machen.

Sonntag, 18. November 2007

Silverlight 1.1 Alpha mit ASP.NET

Um in einem Silverlight-Projekt JavaScript debuggen zu können habe ich folgende Lösung zusammengebaut:

Ausgangspunkt ist eine neue Solution (VS2008 Beta2), in die ein Silverlight-Projekt "SilverlightApp" und ein ASP.NET Projekt "SilverlightWeb" eingefügt wurden.

In SilverlightWeb habe ich einen neuen Ordner "js" hinzugefügt in das ich die Dateien Silverlight.js sowie TestPage.html.js (als CreateSilverlight.js) aus SilverlightApp kopiert habe.

Den Inhalt aus TestPage.html (SilverlightApp) habe ich in in Default.aspx kopiert, wobei die erste Zeile

"<%@ Page Language="C#" ..."
in Default.aspx bestehen bleibt und der Rest durch den Inhalt aus TestPage.html ersetzt wird.

In Default.aspx sind zwei Zeilen entsprechend anzupassen

   1 <script type="text/javascript" src="js/Silverlight.js"></script>
2 <script type="text/javascript" src="js/CreateSilverlight.js"></script>

Damit die benötigten Dateien des SilverlightApp-Projektes in das SilverlightWeb-Projekt kopiert werden ist noch eine Verbindung herzustellen.
Über das Kontextmenü des SilverlightWeb-Projektes "Add Silverlight Link ..." aufrufen und SilverlightApp auswählen.

In den Properties des SilverlightWeb-Projektes Register "Web" kann der Debugger für Silverlight ein- und ausgeschaltet werden, da nur Script- *oder* Silverlight-debugging unterstützt wird.

JavaScript debugging mit Silverlight 1.1 Alpha

Möglicherweise habe ich etwas übersehen, aber ich schaffe es nicht in einem Silverlight Projekt JavaScript zu debuggen.

Breakpoints im Codebehind C#-Code funktionieren, aber Breakpoints im JavaScript-Code werden ignoriert.

Debuggen von JavaScript in ASP.NET-Seiten funktioniert problemlos.

Meine Schlussfolgerung: Es liegt daran, dass im Silverlight-Projekt eine .html-Seite verwendet wird und Debuggen damit nicht unterstützt wird.

Wie ich das Projekt umgebaut habe, damit alles über ASP.NET läuft erläutere ich in einem eigenen Blogpost: Silverlight 1.1 Alpha mit ASP.NET

Silverlight 1.1 Alpha scriptable Methode liefert true anstatt false

Bei meinen ersten Versuchen mit Silverlight (1.1 Alpha) bin ich auf folgenden Bug (?) gestoßen.

Die Methode

   1 [Scriptable]
2 public bool GiveMeFalse()
3 {
4 return false;
5 }

liefert beim ersten Aufruf mit

   1 alert(sl_Plugin.Content.smRootCanvas.GiveMeFalse());

true, bei allen weiteren Aufrufen dann aber den erwarteten Wert false.

Ich verwende als Workaround eine Methode die 0 bzw 1 als int zurückliefert, das funktioniert soweit.

JavaScript Syntax-Highlighting und Intellisense funktioniert in Visual Studio 2008 Beta 2 nicht

Ich verwende den Visual Studio 2008 Beta 2 und Team Foundation Server in der VirtualPC-Variante wie sie von Microsoft zum Download angeboten wird..

Das vielgepriesene Intellisense für JavaScript zeigt sich nicht und nicht mal mehr Syntaxhighlighting funktioniert - das kann nicht sein.

Hier gibts die Lösung Angus Logan's Blog