Apps auf SurfTab per USB debuggen

Endlich funktioniert mein SurfTab als ADB Gerät, so dass ich Apps per USB debuggen kann – eine schwere Geburt, auch wenn es schlussendlich ganz einfach ist:

  1. SurfTab in den Entwicklereinstellungen auf das USB-Debugging vorbereiten
  2. SurfTab per USB-Kabel an den PC anschließen
  3. Im Geräte -Manager nach dem Gerät suchen (mit einem gelben Dreieck markiert)
  4. Über Eigenschaften die Aktualisierung der Treiber starten
  5. Auf dem Computer nach Treiber-Software suchen > Aus einer Liste auswählen
  6. Alle Geräte auflisten > Datenträger wählen
  7. Google USB-Treiber suchen und auswählen und Warnung ignorieren
  8. Gerät vom USB ab- und wieder anstöpseln
  9. Fertig!

Sonderzeichenprobleme in Git Repos beheben

Als ich mit Git zu arbeiten begann, wurden Sonderzeichen (Umlaute, Akzente, etc.) noch nicht unter Verwendung von Unicode behandelt. Nach der Einführung von Unicode (und einem Update auf die entsprechende Version von Git) wurden die ursprünglichen Dateinamen nicht mehr erkannt. Nach dem Neu-Hinzufügen der betroffenen Dateien hatte ich im Index immer zwei Kodierungen des gleichen Dateinamens gespeichert und der alte wurde immer als fehlerhaft und nicht löschbar angezeigt. Dank eines Artikels, den ich gestern gefunden habe, konnte ich nun meine Repos bereinigen.

Hier die Befehle, die ich in der Git Konsole für die Lösung meines Problems verwendet habe (jeweils im Verzeichnis, das Problemdateien enthielt, ausgeführt):

$ git ls-files | grep "\""
$ git rm --cached "`printf "<Datei>"`"
$ git commit -m "clean up bad encoding of file names"

<Datei> = <problematischer Dateiname ggf. unter Verwendung von * oder ? als Platzhalter>

Das ganze dauerte für meine vielleicht 30 Problemdateien nur einige Minuten und nach dem Hinzufügen der nicht mehr indizierten Dateien war mein Repository wieder in einem sauberen Zustand.

NuGet & Xamarin Studio

Gestern bin ich über ein Add-in für Xamarin Studio gestolpert, das den NuGet-Paketmanager in diese Entwicklungsumgebung integriert. Details finden sich auf der Projekt-Homepage. Eine kleine Ergänzung: Die Repository-URL sollte ohne den letzten Pfadbestandteil „main.rep“ angegeben werden, da es sonst einfach nicht funktionieren will; also: http://mrward.github.com/monodevelop-nuget-addin-repository/4.0 statt: http://mrward.github.com/monodevelop-nuget-addin-repository/4.0/main.mrep – „main.rep“ wird dann automatisch ergänzt.

XPS-Dokumente aus WPF-Anwendung heraus erstellen

Um aus einer WPF-Anwendung heraus zu drucken bzw. ein druckbares Dokument zu generieren, bietet sich ein FlowDocument an, das bequem in XAML geschrieben und formatiert werden kann. Über Datenbindung können dann Platzhalter mit konkreten Inhalten belegt werden, indem das Dokument per XamlReader instanziiert wird und, durch Zuweisung an die Eigenschaft DataContext, Daten gebunden werden. Leider scheint das aber nur zu funktionieren, wenn anschließend noch mindestens ein Dispatcher-Aufruf erfolgt. Diese lässt sich aber leicht mit folgender Code-Zeile durchführen:

Dispatcher.CurrentDispatcher.Invoke(
    DispatcherPriority.SystemIdle,
    new DispatcherOperationCallback(arg => null),
    null);

Dieses Dokument kann nun gedruckt oder als XPS gespeichert werden. Letzteres ist zumindest für mich ein akzeptabler Ersatz für PDF und lässt sich mithilfe des XpsSerializationManager leicht bewerkstelligen.
Zu Berücksichtigen ist dabei jedoch, dass hier Zeichenressourcen genutzt werden, die nur in einem STA-Thread laufen dürfen, weswegen die ganze Operation durch einen entsprechenden Aufruf gekapselt werden muss:

Thread thread = new Thread(WriteXpsDocument);
thread.SetApartmentState(ApartmentState.STA);
thread.Start();

Entity Framework – Typen und Ausnahmen

Beim Arbeiten mit dem Entity Framework (EF) bekam ich gestern ständig folgende Ausnahme:

System.Collections.Generic.KeyNotFoundException:
Der angegebene Schlüssel war nicht im Wörterbuch angegeben.

Während der StackTrace von einer „MemberDomainMap“ sprach, bezog ich den Fehler anfangs immer auf einen von mir selbst vergebenen Primärschlüsselwert. Letztlich stellte sich aber heraus, dass eine andere Datenklasse eine Eigenschaft hatte, die nicht vom EF automatisch umgesetzt werden kann – besser gesagt: der Typ dieser Eigenschaft (System.Version) verfügte über kein Standard-Mapping (SQL-CLR Type Mapping).

Auch der Versuch dies mit [Column(TypeName = "ntext")] anders abzubilden und sich dabei auf Parse() und ToString() zu verlassen wie die Dokumentation es vorschlägt schlug fehl. So blieb letztlich nur die „banale“ Lösung, dies zu Fuß zu erledigen:

    [NotMapped]
    public Version Version { get; set; }

    public Version VersionString
    {
        get { return Version.ToString(); }
        set { Version = Version.Parse(value ?? "0.0"); }
    }

Entity Framework – Erste Schritte und Erfahrungen

Meinen Einstieg ins Entity Framework von Microsoft hatte ich bereits vor etwa einem Jahr und seitdem kann ich mir keinen schnelleren und einfacheren Weg mehr vorstellen, um „mal eben“ einen Datenbankzugriff zu realisieren – kein Abstimmen von SQL-Befehlen auf Entity-Klassen, kein Verwalten von Fremdschlüsseln, kein explizites DDL-Skript zur Anlage der Tabellen. Dank des Entity Frameworks kann ich weiter in C# arbeiten, mich auf meine Klassen und Geschäftslogik konzentrieren und das DB-Management delegieren.

Erste Schritte

Das Entity Framework (EF) lässt sich leicht fast jedem Projekt mit dem NuGet-Paket-Manager hinzufügen.

Da ich den „Code First“-Ansatz, bei dem die Klassen automatisch in Tabellen umgewandelt werden, bevorzuge, konzentriere ich mich auf den Entwurf meiner Datenklassen und modifiziere sie leicht, um dem EF Hinweise zu geben, was wie umgesetzt werden soll.

Ein kleines Beispiel

Aus den beiden folgenden Klassen…

public class Diagram
{
    public Guid Id { get; set; }
    public String Name { get; set; }
    public ICollection<Symbol> ContainedSymbols { get; set; }
}

public class Symbol
{
    public Guid Id { get; set; }
    public String Name { get; set; }
    public Diagram ContainingDiagram { get; set; }
}

wird…

public class Diagram
{
    [Key]
    public Guid Id { get; set; }

    [Required]
    public String Name { get; set; }

    public virtual ICollection<Symbol> ContainedSymbols { get; set; }
}

public class Symbol
{
    [Key]
    public Guid Id { get; set; }

    [Required]
    public String Name { get; set; }

    public Guid ContainingDiagramId { get; set; }

    [ForeignKey("ContainingDiagramId")]
    public virtual Diagram ContainingDiagram { get; set; }
}

Das Attribut „Key“ definiert den Primärschlüssel, „Required“ legt fest, dass dieser Wert in der Datenbank nicht NULL sein darf, und „ForeignKey“ definiert die Schlüsseleigenschaft, über die eine „Navigationseigenschaft“ aufgelöst werden soll (oder alternativ die Navigationseigenschaft, die die so gekennzeichnete Schlüsseleigenschaft auflöst). Weiteres dazu findet sich online unter dem Begriff „Code First Data Annotations„.

Bleibt noch der Hinweis, dass die Kennzeichnung der „Navigationseigenschaften“ (Eigenschaften, die „Entitäten“/Datenobjekte miteinander verbinden) mit virtual dafür sorgt, dass das EF „lazy loading“ einsetzen kann, um den Inhalt bereitzustellen, sprich: die Daten werden nicht sofort bereitgestellt, sondern erst abgerufen, wenn sie wirklich benötigt werden.

Einen Kontext erstellen

Nachdem die Datenklassen wie oben beschrieben bereitstehen, fehlt nur noch der DbContext, der den Zugriff auf die Datenbank kapselt:

public class DiagramContext : DbContext
{
    public DbSet<Diagram> Diagrams { get; set; }

    public static void PopulateDatebase()
    {
        using (DiagramContext dc = new DiagramContext())
        {
            Diagram dgm = new Diagram();
            dgm.Id = Guid.NewGuid();
            dgm.Name = "Ein erstes Diagramm";

            dc.Diagrams.Add(dgm);
            dc.SaveChanges();
        }
    }
}

Erfahrungen

Bislang habe ich meinen DbContext in jeder ASP.NET MVC-Action neu erstellt und mit using geklammert. Inzwischen hat sich aber gezeigt, dass beim weiterreichen von Abfrageergebnissen an Views Probleme entstehen können, wenn die Abfragen nicht mit .ToArray() oder .ToList() komplett ausgeführt wurden, da nach dem verlassen des using-Blocks der DbContext bereits „disposed“ ist. Ein besserer Weg ist das definieren eines DbContext-Attributs in der MVC-Controller-Klasse, das im Konstruktor (oder direkt) initialisiert und in einer Dispose()-Überschreibung „disposed“ wird.

Metro App: Breite der Items im ListView kontrollieren

Standardmäßig haben die Elemente in einem ListView eine Breite, die ihrem Inhalt entspricht und werden durch den ListView selbst nur in ihrer maximalen Breite beschränkt. Wenn allerdings alle Elemente die gleiche Breite, vorzugsweise die maximal zulässige Breite eines Elements im ListView, haben sollen, dann muss der ItemContainerStyle angepasst werden:

<ListView.ItemContainerStyle>
    <Style TargetType="ListViewItem">
        <Setter Property="HorizontalContentAlignment" Value="Stretch" />
    </Style>
</ListView.ItemContainerStyle>

Random Crash

System.Random ist nicht Thread-sicher! Bei „gelichzeitigem“ Aufruf aus verschiedenen Threads, gibt Next() irgendwann nur noch „0“ zurück. Um dies zu verhindern, muss entweder jeder Aufruf an eine Random-Instanz durch „lock ()“ umschlossen werden:

lock (MyRandomMember)
{
    MyRandomMember.Next();
}

oder jeder Thread erhält eine eigene Random-Instanz, was bequem über das Attribut „ThreadStatic“ möglich ist:

[ThreadStatic]
private static Random _myRandomMember;

private static Random MyRandomMember
{
    get { return _myRandomMember ?? (_myRandomMember = new Random()); }
}

SASS & Compass – komplexes CSS einfach managen

Compass ist ein großartiges Tool, um ein Webprojekt auch nachträglich mit Foundation „aufzupeppen“. Außerdem erledigt es nebenbei alle nötigen Arbeiten, um Anpassungen am Framework sofort als CSS bereitzustellen. Und wenn man schon mal dabei ist, kann man auch gleich SASS nutzen, um seine eigenen Styles einfacher zu managen.

Compass installieren

Compass benötigt Ruby und ist dann sehr einfach zu installieren:

gem update --system
gem install compass

Bestehendes ASP.NET MVC4 -Projekt erweitern

Um ein typisches Webprojekt um Compass-Unterstützung zu erweitern, müssen lediglich die folgenden Befehle ausgeführt werden:

cd <myproject>
compass create --bare --sass-dir "Content\sass"
    --css-dir "Content" --javascripts-dir "Scripts"
    --images-dir "Content\images"

Verzeichnisüberwachung starten

Mit dem Befehl „compass watch“ kann das akuelle Verzeichnis überwacht werden – der Watcher startet aber nur, wenn es schon eine *.SASS oder *.SCSS Datei zu überwachen gibt, weswegen vorher im Verzeichnis „.\Content\sass“ z.B. eine Datei „Styles.scss“ händisch angelegt werden sollte.

Foundation mit Compass installieren

Wie auf der Foundation-Homepage beschrieben, ist es sehr einfach, Foundation zu installieren:

gem install zurb-foundation

oder zu aktualisieren:

gem update zurb-foundation

Ist ein Projekt bereits für Compass eingerichtet, liegt eine „config.rb“ Datei im Projektverzeichnis. Diese muss (am besten am Anfang) um den Eintrag require "zurb-foundation" ergänzt werden, was dann die Ausführung des folgenden Befehls ermöglicht:

compass install foundation

Und damit ist das Projekt dann auch schon bereit für den Einsatz von Foundation!

XAML: Unterschiede in der Namespace-Deklaration Phone / Store Apps

Wie ich gerade feststellen musste, arbeiten in Visual Studio 2012 die XAML-Editoren/-Compiler für WinStore-Apps und WinPhone 8-Apps unterschiedlich, wenn es um die Referenzierung von Klassen im eigenen Assembly geht. Während bei Phone-Apps die Angabe xmlns:local=“clr-namespace:JochenLinnemann.DiceRoller“ durchaus akzeptiert wird, muss es bei Store-Apps xmlns:local=“using:JochenLinnemann.DiceRoller“ heißen.