.NET User Group in Bielefeld am 21.06.2010

Friday, June 18, 2010 11:07:25 AM (W. Europe Daylight Time, UTC+02:00)

Bereits vor einigen Jahren gab es schon einmal die .NET User Group Bielefeld. Nachdem Henner – der die Gruppe damals organisierte – aber seinen Arbeitgeber gewechselt hatte, fand sich kein Nachfolger für die Organisation der User Group.

Inzwischen hat Henner eine eigene Firma und ich bin von Paderborn nach Werther (bei Bielefeld) gezogen. Deshalb werden wir zusammen erneut die Treffen der .NET User Group in Bielefeld organisieren.

Da unsere alte Domain dotnet-bielefeld.de noch immer bei Henners ehemaligem Arbeitgeber liegt und die Übergabe sich nun schon seit Wochen verzögert gibt es die Infos zur User Group vorläufig hier im Blog.

Das 1. Treffen ist am 21.06.2010 um 18 Uhr. Wir treffen uns bei Xavannah in der Karl-Oldewurtel Straße 40 in Bielefeld. Der Treffpunkt ist sowohl über die A2/A33 als auch mit der Bahn gut erreichbar.

Unter anderem werde ich ein wenig über Visual Studio 2010 Extensibility erzählen.

Kick it on dotnet-kicks.de

Warum ich nicht mehr bei Aral/BP tanke

Friday, June 11, 2010 11:34:58 AM (W. Europe Daylight Time, UTC+02:00)

Nachdem ein Kommentar von mir auf Twitter ("Nochmal zur Erinnerung für's nächste Tanken: Aral = BP") zu einigen Antworten von @writeline und @_zif_ geführt hat, und 140 Zeichen einfach zu kurz sind, ausführlich darauf zu antworten, kommentire ich das mal etwas ausführlicher hier im Blog.

In den Kommentaren ging es in etwa darum, ob es Sinn macht, BP/Aral zu boykottieren, und ob wir nicht als Autofahrer sowieso eine Mitschuld tragen.

Ist man als Autofahrer oder allgemein Verbraucher von Öl mitschuld an der Umweltkatastrophe im Golf? Ich würde sagen nein, so direkt kann man das nicht sagen, denn gerade beim Benzin und anderen Ölprodukten fehlt mir als Verbraucher die Möglichkeit zu erkennen, wie diese Produkte entstanden sind.

Ich bin gerne bereit, für "vernünftig" hergestellte Produkte auch mehr zu bezahlen. Wenn ich z.B. Eier kaufe und nicht mit bestimmten Haltungsbedingungen einverstanden bin, kann ich Bio-Eier kaufen. Bei vielen anderen Lebensmitteln habe ich ähnliche Wahlmöglichkeiten. Und die nutze ich auch.

Aber beim Öl? Bestenfalls über die Wahl meines Stromanbieters habe ich da einen einigermaßen großen Einfluss (hier nutze ich 100% Ökostrom von NaturWatt).

Wenn ich tanke sehe ich nicht, ob das Benzin aus Öl hergestellt wurde, das "vernünftig", also unter Einhaltung aller Sicherheitsstandards, vernünftiger Arbeitsbedingungen für die Mitarbeiter usw. gefördert wurde. Ich sehe nicht, wo es herkommt – ob von irgendeiner Bohrinsel, oder einem Bohrturm in der Wüste. Ob dabei viel Natur zerstört wurde oder nicht. Es gibt kein Gegenstück zu “Bio” bei Lebensmitteln, das irgendetwas darüber aussagt, wo das Öl herkommt.

Echte Alternativen gibt es auch nicht. Elektroautos z.B. sind für mich einfach nicht bezahlbar. Der ÖPNV scheidet aus wegen mangelnder Verbindungen und überhöhter Preise. Bestenfalls kann ich also ein kleines, sparsames Auto fahren (und das mache ich auch - ich bin allgemein sowieso kein Fan großer Autos).

Die einzige Einflussmöglichkeit, die ich sonst noch sehe, ist die Wahl der Tankstelle. Deshalb tanke ich nicht mehr bei BP/Aral. Möglicherweise (wahrscheinlich sogar) sind die meisten anderen Anbieter auch nicht besser. Aber ich habe keine Möglichkeit, das irgendwie zu überprüfen. Bei BP weiß ich zumindest, dass sie (mit großer Wahrscheinlichkeit) Schuld sind an dem, was da am Golf passiert. Ich weiß nicht, ob BP alle Sicherheitsstandards eingehalten hat oder nicht, aber zumindest weiß ich, dass sich BP vorher anscheinend überhaupt keine Gedanken gemacht hat, wie man im Katastrophenfall handeln soll. Das trifft dann zwar (leider) auch den unschuldigen Tankstellenpächter, aber einen anderen Weg sehe ich nicht.

Kick it on dotnet-kicks.de

dotnet Cologne 2010

Saturday, May 29, 2010 1:19:51 PM (W. Europe Daylight Time, UTC+02:00)

Gestern war wieder dotnet Cologne. Dieses Jahr noch größer mit 300 Teilnehmern und deshalb auch nicht in der Microsoft Niederlassung in Köln, sondern im Holliday Inn Am Stadtwald.

Ich war mit zwei Vorträgen dabei:

  • Visual Studio 2010 Extensibility (Folien)
  • Internationalisierung von WPF Anwendungen mit NLocalize (Folien)

Beide Vorträge waren gut besucht und das Feedback der Teilnehmer nach den Vorträgen (insbesondere bei NLocalize) sehr positiv.

Leider bin ich selbst mal wieder nicht wirklich dazu gekommen, mir Vorträge anzusehen. Die Vorträge, die mich am meisten interessiert hätten, liefen immer dann, wenn ich gerade keine Zeit hatte. Wenn ich Zeit hatte ging es meistens um Grundlagen zu irgendwelchen Themen, die ich selbst schon kannte. Trotzdem war es eine sehr gelungene Veranstaltung mit vielen Möglichkeiten zum Networking. Sehr gut gefallen hat mir auch die Grillparty des dotnet-Forums, die im Anschluss an die dotnet Cologne stattgefunden hat.

Weniger zufrieden war ich mit dem Hotel. Die 99€ pro Nacht waren absolut unangemessen, ich habe schon oft in schöneren Zimmern für deutlich weniger Geld übernachtet. Dazu kamen dann noch absolut unverschämte und meiner Meinung nach schon an Betrug grenzende Preise für Internet und Telefon, und 10€ pro Tag Parkgebühren. Internet für 7€ / Std, Ortsgespräche für 50 cent / Minute, deutschlandweit für 1€ / Minute und ins Mobilfunknetz für 1,50€ / Minute. Da fragt man sich, ob das Hotel per Satellitentelefon an das Telefonnetz angeschlossen ist (tatsächlich sind die Gebühren für Satellitentelefongespräche sogar teilweise günstiger). Zum Glück habe ich nicht telefoniert. Hätte ich versehentlich (ohne die Preise zu sehen) telefoniert, hätte ich mich jedenfalls geweigert, solche Gebühren zu bezahlen. Für mich heisst das jedenfalls, dass ich nicht noch einmal in einem Holliday Inn übernachte, sofern es sich irgendwie vermeiden lässt.

Kick it on dotnet-kicks.de

Ressourcen zum Einstieg in die .NET Entwicklung

Thursday, February 11, 2010 3:01:08 PM (W. Europe Standard Time, UTC+01:00)

Zu .NET gibt es von Microsoft und in Blogs usw. sehr viele gute Videos, Tutorials und sonstige Ressourcen. Da ich gerade auf Twitter nach Empfehlungen gefragt wurde hier eine kleine Übersicht:

Englisch:

Das “Beginner Developer Learning Center” fängt wirklich bei Null an. Gerade für absolute Einsteiger ohne Programmiervorkenntnisse ist es ein guter Einstieg, sofern man gute Englischkenntnisse mitbringt.

http://msdn.microsoft.com/en-us/beginner/default.aspx

Deutsch:

MSDN Webcasts sind Onlinevorträge, die Live und anschließend als Aufzeichnung angeboten werden.

Aktuell befinden sich über 800 Webcasts im MSDN Archiv, genug Material, um einen Monat ohne Pause 24h am Tag Video zu schauen ;-). Webcasts gibt es in verschiedenen Schwierigkeitsstufen und zu beinahe jedem Thema. Beim finden des passenden Webcasts hilft der Webcast Finder, http://www.microsoft.com/germany/msdn/webcasts/finder/default.mspx

(da findet man sogar noch meinen Webcast von 2006 zum Imagine Cup…)

Während Webcasts jeweils ein Thema ausführlich behandeln, geht es bei MSDN Solve Code Clips darum, zu konkreten Fragen gezielt antworten zu liefern. http://www.microsoft.com/germany/msdn/solve/default.mspx

Bei Fragen und Problemen helfen zahlreiche Online- und Offlinecommunities. Neben den offiziellen MSDN Foren (http://social.msdn.microsoft.com/Forums/de-de/categories/) gibt es zahlreiche Communityforen, Blogs und User Groups. Eine Übersicht gibt es im Microsoft Community Guide: http://www.microsoft.com/germany/community/developer/default.mspx

Technorati Tags: ,,,
Kick it on dotnet-kicks.de

Lokalisierung von WPF Anwendungen: Die Lokalisierungs-API

Sunday, December 27, 2009 5:00:00 PM (W. Europe Standard Time, UTC+01:00)

Dies ist der zweite Teil einer Artikelserie zu Lokalisierung von WPF Anwendungen. Nach einem allgemeinen Überblick über die Lokalisierung in Teil 1 erkläre ich in diesem Artikel, wie man WPF Anwendungen mit der WPF Lokalisierungsapi lokalisieren kann.

Satellitenassemblies

Soll eine Anwendung in mehrere Sprachen übersetzt werden, erzeugt man für jede Sprache eine Satellitenassembly, die alle zu übersetzenden Resourcen (Texte, Bilder usw.) in der jeweiligen Zielsprache enthält.

image

In WPF wird anders als in Windows Forms oder ASP.NET nicht mehr .resx als Resourcenformat für die Lokalisierung verwendet. Stattdessen werden komplette Formulare bzw. Steuerelemente in übersetzter Form in den Satellitenassemblies der jeweiligen Sprachen gespeichert.

Lokalisierung über .baml Dateien

WPF Formulare und Steuerelemente werden über .xaml Dateien beschrieben. Diese werden beim Übersetzen der Anwendung in ein binäres Format (.baml) übersetzt. Die .baml Dateien werden als Resourcen in den Assemblies der Anwendung gespeichert. So wird z.B. aus einer MainWindow.xaml eine MainWindow.baml, die dann z.B. in der Assembly Anwendung.exe als Resource gespeichert wird.

Wenn nun ein Formular bzw. Steuerelement in einer weiteren Sprache angeboten werden soll, muss die dazugehörige .baml Datei übersetzt als Resource in einer Satellitenassembly der Zielsprache vorliegen.

image

Um eine WPF Anwendung zu übersetzen müssen wir also die .baml Dateien der Anwendung übersetzen und in Satellitenassemblies speichern.

Außerdem benötigen alle Elemente in unseren .xaml Dateien, die übersetzt werden sollen, eine (pro Datei) eindeutige Bezeichnung in Form eines x:Uid-Attributs (mehr dazu in einem späteren Artikel).

Leider gibt es dafür keine Unterstützung in Visual Studio oder Blend. Auch in Visual Studio 2010 wird sich daran nichts ändern.

Die WPF Lokalisierungs-API

Stattdessen gibt es eine API, über die lokalisierte BAML Dateien erzeugt werden können. Diese API besteht im Kern aus einer Klasse, der Klasse BamlLocalizer.

BamlLocalizer

image

Die Klasse BamlLocalizer kann aus einer .baml Datei Resourcen extrahieren (ExtractResources-Methode) und später mit übersetzten Resourcen eine lokalisierte .baml Datei erzeugen (UpdateBaml-Methode).

Zunächst benötigen wir Zugriff auf die .baml Datei. Wir haben ja bisher nur die .xaml Dateien, für die BamlLocalizer-Klasse benötigen wir aber die binäre Form der .xaml Dateien im BAML Format.

Für den Zugriff auf die .baml Dateien bieten sich mindestens zwei Wege an: wir könnten die .baml Dateien aus dem fertig übersetzten Assemblies laden, oder die Dateien verwenden, die als “Zwischenprodukt” bei der Übersetzung unserer Anwendung anfallen.

Die erste Variante wird von Microsoft empfohlen und in Beispielen für die Lokalisierungs-API verwendet. Persönlich finde ich diesen Weg jedoch umständlicher, in meinen eigenen Lokalisierungstools verwende ich deshalb die .baml Dateien, die sowieso als “Abfallprodukt” bei der Übersetzung unseres Projekts erzeugt werden (diese Dateien befinden sich normalerweise “irgendwo” im Unterverzeichnis “obj” des WPF-Projekts).

Um eine .baml Datei übersetzen zu können, benötigen wir Zugriff auf die in der .baml Datei enthaltenen Resourcen (also Texte und sonstige Eigenschaften von Objekten, die wir übersetzen bzw. anpassen möchten). Diese Resourcen erhalten wir, indem wir die .baml Datei als Stream an den BamlLocalizer übergeben und die ExtractResources-Methode aufrufen.

image

BAML Resourcen – Das BamlLocalizationDictionary

Von der ExtractResources-Methode erhalten wir ein BamlLocalizationDictionary-Objekt, das alle Resourcen der .baml Datei enthält.

image

Jede Resource besteht aus einem Schlüssel und dazugehörigen Werten.

Der Schlüssel ist vom Typ BamlLocalizableResourceKey. Er besteht aus dem Namen der Eigenschaft, die in dem Eintrag gespeichert ist (PropertyName, z.B. “Text”), der Klasse, zu der diese Eigenschaft gehört (ClassName, z.B. “TextBlock”), dem Namen der Assembly, in der diese Klasse gespeichert ist (AssemblyName) und einer eindeutigen Bezeichnung (Uid). Die Eigenschaften des Schlüssels sind nicht veränderbar.

Zu jedem Schlüssel sind verschiedene Werte in Form eines BamlLocalizableResource-Objekts gespeichert. Die Wichtigste Eigenschaft dieses Objekts ist die Eigenschaft Content, über die der Wert der Eigenschaft gespeichert wird (z.B. “Hello World” als Wert für die Text-Eigenschaft des TextBlock-Objekts). Das ist der Wert, den wir übersetzen möchten. In den weiteren Eigenschaften können wir Informationen für den Übersetzer hinterlegen, der unsere Resourcen für uns übersetzen soll. In der Eigenschaft Comments können wir z.B. Kommentare und Hinweise für den Übersetzer speichern. Modifiable legt fest, ob der Übersetzer überhaupt diese Eigenschaft übersetzen darf. Mit Readable können wir festlegen, ob eine Eigenschaft für den Übersetzer sichtbar ist oder nicht. Über LocalizationCategory werden Resourcen in verschiedene Kategorien einteilen, z.B. “Text”, “Label”, “Button” usw..

Um die Einträge im BamlLocalizationDictionary übersetzen zu können, müssen wir die Inhalte des Dictionaries in irgendeiner Form speichern, z.B. in eine Datei oder in eine Datenbank. Dafür gibt es keine Klassen in der WPF Lokalisierungs-API, wir müssen also eigenen Code schreiben. Es gibt lediglich ein Beispiel dafür in der MSDN (locbaml), zu dem ich später noch etwas schreiben werde.

image

Diese Datei können wir nun selbst übersetzen oder an einen Übersetzer weitergeben, der die Datei für uns übersetzt. Problematisch ist dabei allerdings, dass so sehr leicht ungültige Dateien erstellt werden können (z.B. wenn bei einer Eigenschaft wie “Width” ein Text statt einer Zahl eingegeben wird, ein Teil des Schlüssels geändert wird, oder einfach nur ein Komma falsch gesetzt wrid).

image

Aus der übersetzten Datei müssen wir nun wieder ein BamlLocalizationDictionary erzeugen. Dafür ist wieder eigener Code erforderlich.

image

Wir haben nun ein BamlLocalizationDictionary mit den übersetzten Resourcen. Dieses können wir an die UpdateBaml-Methode der BamlLocalizer-Klasse übergeben, um eine lokalisierte .baml Datei zu erzeugen.

image

Lokalisierte Satellitenassemblies erzeugen

Als Ergebnis erhalten wir eine lokalisierte .baml Datei. Diese müssen wir nun noch in einer Satellitenassembly speichern. Dafür gibt es wieder mindestens zwei Alternativen.

Microsofts locbaml-Beispiel erzeugt die Satellitenassembly selbst komplett neu. Das Beispiel berücksichtigt allerdings keine Resourcen aus anderen Quellen (z.B. .resx), so dass eine so erzeugte Satellitenassembly die Satellitenassembly mit den .resx-Resourcen einfach überschreibt. Außerdem kann locbaml keine signierten Satellitenassemblies erzeugen.

In meinen eigenen Lokalisierungstools nutze ich stattdessen die MSBuild-Skripte aus, die Visual Studio zur Kompilierung von WPF-Projekten verwendet. Die lokaliiserten .baml Dateien werden so von MSBuild genauso behandelt wie evtl. vorahndene andere Resourcen im Projekt (.resx usw.), und von den WPF-MSBuild-Skripten selbst in die Satellitenassemblies geschrieben. Dadurch gibt es keine Probleme mit anderen Resourcen, und die Satellitenassemblies werden “ganz normal” signiert, falls das so in den Projekteigenschaften konfiguriert wurde. Eventuell schreibe ich später dazu einen eigenen Artikel, da ich diesen Ansatz bisher nirgendwo sonst gesehen habe.

Fazit

Lokalisierung über die WPF Lokalisierungs-API ist umständlich. Fertige Tools gibt es nicht, es gibt lediglich ein Beispielprogramm für die API (dazu später mehr in einem eigenen Artikel).

Vorteil dieses Ansatzes ist, dass am Xaml-Code selbst keine Änderungen erforderlich sind, mal abgesehen von zusätzlichen x:Uid Attributen. Somit gibt es keine Probleme bei der Darstellung mit anderen Tools (Blend oder Visual Studio).

In den nächsten Teilen dieser Serie werde ich eventuell noch Alternativen zur WPF Lokalisierungs-API vorstellen. Außerdem möchte ich die Verwendung des locbaml-Beispiels erklären und zeigen, wie sich das locbaml-Beispiel anpassen und erweitern lässt.

Technorati Tags: ,
Kick it on dotnet-kicks.de
«Older Posts