DVB.NET und VCR.NET nun auf GitHub

Ich bin dabei, die Entwicklung meiner privaten aber öffentlichen Projekte von SVN auf GIT umzustellen. Dabei hat es nun auch DVB.NET und VCR.NET erwischt. Da ich die Historie von SVN nicht übertragen habe, gibt es im Moment nur den jeweils aktuellen, nicht stabilen (!) Entwicklungsstand der Version 4.2 – mit allen Fehlern, die so passieren. Sobald die 4.2 abgeschlossen ist werde eine entsprechende Markierung vornehmen – das kann aber noch etwas dauern. Inzwischen gilt: anschauen: gerne, spielen: gerne, produktiv nutzen: nur mit äußerster Vorsicht und ohne Gewähr auf eigene Gefahr – Support gibt es nur mit vorheriger Rücksprache!

Einen schönen Tag

Jochen

Silverlight und WPF Bindings – leicht missbraucht?

Manchmal ist es doch überraschend, an welchen Stellen Bindings verwendet werden können. So handelt es sich bei der Width Eigenschaft einer ColumnDefinition im Grid um eine DependencyProperty, die man dynamisch binden kann. Mit ganz witzigen Effekten, wie ich nun beschreiben möchte – hier eine schnelle Lösung, elegant wird es erst bei Einsatz von ValueConvertern.

In einem privaten Projekt werden zu einer Buslinie die Haltestellen und deren Abstand eingegeben. Ich wollte nun so einen so schönen Zeitstrahl haben, wie man ihn hier in der Gegend auf den ausgegängten Busfahrplänen findet.

Zeitstrahl

Im Programm sind bereits die Haltestelle als Objekte (Knotenpunkt) vorhanden, die INotifyPropertyChanged implementieren. Eine dieser Eigenschaften ist die Fahrzeit zwischen zwei Haltestellen in Minuten. Ich habe nun eine neue Eigenschaft der Art GridLength hinzugefügt – wie gesagt, ein ValueConverter würde eine sauberere Trennung der Softwareschichten bedeuten. Diese Eigenschaft meldet entweder als Breite 0 Pixel (wenn die Fahrzeit 0 ist) oder die (positive) Fahrzeit mit dem GridUnitType.Star – entsprechend der XAML Texteingabe 1*, 2*, 3* etc.

Ein UserControl (FahrplanAnzeigen) wird nun an eine Liste von Haltestellen gebunden – die Liste selbst wird nur sehr faul überwacht und Änderungen führen zu einem vollständigen Neuaufbau: in einem echten Stück Software würde man das sicher optimieren. Für jede Haltestelle wird eine ColumnDefinition erzeugt und die beschrieben Eigenschaft über die BindingOperations an die Width gebunden.

Silverlight sorgt nun mit ein bisschen XAML Definition automatisch dafür, dass die Haltepunkte proportional über den Zeitstrahl verteilt werden. Reaktionen bei Änderung der Größe sind nicht notwendig. Mehr noch: ändert man die Fahrzeit eines Haltepunktes im Formular, so passt sich der Zeitstrahl über das Binding ohne irgendwelche weitere Interaktion des Programms an. Das sieht schon recht witzig aus – vor allem für ein geschenktes Feature.

Happy Coding

Jochen

Silverlight 5 vs. ANSI (Windows-1252) Encoding

Für eine kleine Auftragsarbeit im Familienkreis will ich mit Silverlight 5 eine XML Datei lesen und schreiben – als Ersatz für den Schedule Wizzard des Bus Simulator 2012 Spiels, der unter Windows XP nicht richtig funktioniert. Wenn man allerdings versucht, eine lokale Datenstrom in ein XDocument zu laden oder ein solches zu schreiben, so gibt es eine kleine Überraschung: von Hause aus unterstützt Silverlight das Windows Encoding und esp. die 8-Bit Windows Codepage 1252 nicht.

Tatsächlich sind die hier verwendeten Dateien genau betrachtet auch unzulässig, allerdings drücke ich doch allzu gerne beide Auge zu, da ich selbst schon oft in diese Falle gelaufen bin. Hier werden XML Dateien verwendet, in deren ?xml Instruktion kein Encoding angegeben ist, die aber tatsächlich in der 8-Bit Codepage 1252 von Windows verfasst sind. Das heißt zum Beispiel, dass das €uro Symbol mit dem Wert 128 hinterlegt ist – entsprechend auch die Umlaute. Silverlight wird eine solche Datei mit 1252er Umlauten erst gar nicht laden und beim Speichern das UTF-8 Format verwenden – inklusive einem korrekten Encoding in der ?xml Instruktion. Damit kommt aber das Spiel nicht zurrecht.

Ich habe ohne langes Suchen eine kleine eigene Implementierung verwendet, die ich hier kurz vorstellen will – recht trivial und meiner Ansicht nach dem Zweck angemessen. Die Implementierung selbst findet man in diesem Archiv.

Erst einmal habe ich mir (mit Hilfe vom richtigen .NET und dem Encoding.GetEncoding(1252)) eine Abbildungsvorschrift zwischen Windows 1252 Bytes und 16-Bit UNICODE Zeichen erstellt und diese in Silverlight eingebunden (man siehe hierzu Fahrplan.cs im Archiv). Beim Laden wird die gesamte Datei (die für die konkrete Anwendung extrem klein ist) binär als byte-Feld unverändert eingelesen. Mit Hilfe der Abbildungsvorschrift wird pro byte das zugehörige UNICODE Zeichen als char erstellt, i.e. 128 gibt € und so weiter. Dieses char-Feld bildet dann eine Zeichenkette via new string(feld) und über die System.IO.StringReader Klasse kann das XDocument klaglos erstellt werden.

Das Speichern ist ein wenig trickreicher. Hier wird das XDocument erst einmal im Speicher mit Hilfe einer MemoryStream Instanz gespeichert. Der Einsatz von XmlWriter und XmlWriterSettings erlaubt es dabei, das Encoding auf Encoding.Unicode zu fixieren. Die UNICODE char Zeichen im Speicher werden nun alle über die Abbildungsvorschrift in Windows 1252 Bytes umgesetzt – ist dies nicht möglich, wird ein ? als Ersetzungszeichen verwendet. Der erste char wird dabei ignoriert, hier würde in der Datei die BOM (Byte-Order-Mark) stehen, die eine Identifikation des Dateiinhaltes als UNICODE ermöglichen soll. Somit wird aus einem ursprünglichen UNICODE char-Feld einfach ein byte-Feld in Windows 1252 Codierung, das dann binär in eine lokale Datei gespeichert wird. Aber Vorsicht: hier ist in der ?xml Instruktion immer noch das Encoding als UTF-16 festgelegt, was zumindest von der Originalformatierung abweicht. Im Programmcode werden die entsprechenden Bytes beim Schreiben der Datei entfernt.

Etwas ekelig, aber nicht so schlimm, wie es sich anhört. Der eigentliche Code zum Lesen und Schreiben sind wenige Zeile und die lange Abbildungsvorschrift kann man sich leicht automatisiert erstellen. Besser als ein eigenes Encoding, oder?

Soweit zum Thema: Was Sie eigentlich nie über Silverlight wissen wollten aber gezwungen waren sich damit auseinander zu setzen 🙂

Jochen

Kinderkram

Mal wieder ein kleines Intermezzo. Die Frage meines Sohnes “Papa, kannst Du nicht ein Jump&Run programmieren?” konnte ich natürlich 🙂 nicht einfach so im Raum stehen lassen. Da ich mich eh weiterhin in Silverlight einarbeiten wollte, habe ich mich entschieden, mal einen Prototyp zu erstellen. Viel kann er zwar nicht, aber so mit einer Spielfigur rumlaufen, Dinge einsammeln etc. funktioniert schon. Der Code für diese erste Variante ist schon fertig (auch öffentlich über das Hilfedokument verfügbar, man siehe darin den Link ganz unten), an den optischen und aktustischen Effekten arbeiten wir noch – so kann die Spielfigur beim Laufen auch animiert werden, dazu muss man aber Bildsequenzen erstellen, was recht lästig ist.

Den aktuellen Stand möchte ich dem geneigten Leser aber nicht vorenthalten.

Have Fun

Jochen

ListBox, ComboBox oder was?

Im Rahmen meiner Einarbeitung in Silverlight / WPF bin ich auf eine Idee gestossen, die ich einmal an einem rudimentären Beispiel als Anschauungsmaterial implementiert habe. Die Aufgabenstellung an sich ist eigentlich sehr einfach: aus einer begrenzten Liste von Auswahlelementen soll eines vom Anwender ausgewählt werden. Ganz klar die Aufgabe einer ComboBox. Die Auswahl soll zudem graphisch und nicht in Textform präsentiert werden – auch keinerlei Herausforderung für Silverlight / WPF. Wie das Beispiel zeigt, kann man sich das auch optisch ein wenig anders vorstellen – zu den einzelnen Elementen der Testseite gleich mehr.

Startzustand

Im initialen Zustand wird die Auswahlliste als ListBox dargestellt – ohne die typische Sondervisualisierung der ComboBox mit dem Auswahlfeld zum Aufklappen. Verändert sich die Auswahl, so übernimmt die Listbox die Anzeige – auf Aspekte des ausgewählten Eintrags kann im XAML wie gewohnt referenziert werden, wie das Bild links oben und der relative Pfad des Bildes daneben zeigt. Das ist nun wirklich nichts Besonderes bis hierhin.

Aufgeklappt

Die Besonderheit zeigt sich aber, wenn man die Auswahl bestätigt. Die ListBox klappt dann scheinbar zu und zeigt nun nur noch den ausgewählten Eintrag.

Zugeklappt

Das Beispiel kann man sich selbst einmal hier anschauen, die Quellen gibt es hier. Es handelt sich wirklich nur um eine sehr elementare Implementierung, sicher nicht um ein vollwertiges Control. Was tut das Beispiel jetzt schon:

  • Beim Starten ist einer der drei Alternativen ausgewählt – sieht im Beispiel etwas häßlich aus, da meine Beispielbilder einen teilweise transparenten Hintergrund haben und die Auswahleinfärbung der Listbox auch im zugeklappten Modus erscheint: einfach vorstellen, dass der Hintergrund der Visualisierungselemente nicht transparent ist (man kann irgendein FrameworkElement verwenden).
  • In der oberen Zeile wird die Auswahl zur Demonstration als Bild und Pfad zusätzlich angezeigt.
  • Ein einfacher Klick auf die gewählte Alternative (großes Bild) öffnet die Auswahlliste.
  • Die Navigation in der Liste mit Maus oder Tastatur verändert die Auswahl, insbesondere kann diese wie gewohnt mit Strg-Click aufgehoben werden.
  • Ein Doppelklick oder die Taste ENTER beendet die Auswahl und schließt die Liste, es wird nun die letzte Auswahl angezeigt.
  • Die Eingabe des Pfades in der oberen Zeile kann zur Änderung der Auswahl verwendet werden – uh, Injection Attack möglich, schert hier aber nicht.
  • Hat die zugeklappte Liste den Fokus, so kann die Auswahl weiterhin mit der Maus verändert werden – die Liste klappt dazu automatisch auf.
  • Im XAML der Seite sieht man, dass die Auswahl vorbelegt werden kann, was natürlich optional ist.

Happy Coding

Jochen