Mal ein Beitrag vollkommen Off-Topic. Wir waren gerade mit unserer Tochter in der Alice im Wunderland Inszenierung des Jugendtheaters Kleinenberg. Ehrlich gesagt hatten wir eine Aufführung auf dem Niveau der üblichen Schulaufführungen erwartet.

Gesehen haben wir ein freches und witziges Musical für Kinder und Erwachsene. Schauspieler und Stück haben sehr gut gefallen, alle Rollen waren sehr gut besetzt. (Natürlich merkt man insbesondere bei den kleineren Nebenrollen, das es keine Profischauspieler sind, aber das ist bei völlig Ok) Das Stück ist eine behutsam modernisierte Musicalfassung des zeitlosen Kinderbuches von Lewis Carroll.  Das Publikum wird immer wieder auf gekonnte Art und Weise in das Stück einbezogen. Da hüpft zwischendurch auch schon mal das weiße Kaninchen auf Sprungschuhen an  den Zuschauern vorbei.

Die Bühne ist sehr klein, aber die Art und Weise wie der verfügbare Raum immer wieder neu genutzt wird, mal mit verschiebbaren Wänden, mal mit Tüchern, mal mit dem sehr gut dosiertem Einsatz von Projektionen, ist wirklich beeindruckend.

Mein Fazit: Hat sich auf jeden Fall gelohnt, nicht nur unsere Tochter, auch wir hatten viel Spaß an ihrem ersten Theaterbesuch. Wir kommen auf jeden Fall wieder.

imageEs ist nicht besonders selten, das wir Entwickler Listen mit Gruppierungen in irgendeiner Form darstellen müssen. Leider ist das auf dem Windows Phone nicht out-of-the-box möglich. Meine ersten Ansätze mit CollectionViewSource zu arbeiten wie von Bea Stollnitz beschrieben, schlugen fehl weil Silverlight auf dem Phone die GroupDescription nichtunterstützt. PagedCollectionViewSource geht auch nicht, so was tun?

Schlussendlich folgte die Lösung dem Motto ‘Back to the Basics’.

Zuerst brauchen wir eine gruppierte Liste als Basis. Hier verwende ich eine einfache ViewModelBase Klasse als Basisklasse, aber im Grunde ginge auch INotifyPropertyChanged (hab ich aber nicht getestet). Die Gruppierung erzeuge ich über LINQ on the fly aus einer flachen Liste:

       /// <summary>
        /// A collection for ItemViewModel objects.
        /// </summary>
        public ObservableCollection<ItemViewModel> Items { get; private set; }

       /// <summary>
        /// A collection for Category and ItemViewModel objects.
        /// </summary>
        public ObservableCollection<ViewModelBase> CategoriesAndItems { get; private set; }

        /// <summary>
        /// Creates and adds a few ItemViewModel objects into the Items collection.
        /// </summary>
        public void LoadData()
        {
            // Sample data; replace with real data
            this.Items.Add(new ItemViewModel() { 
                                  Id=Items.Count, 
                                  Group="Group 1", 
                                  LineOne = "runtime one",
                                  LineTwo = "Maecenas ... bibendum" });
                // ....
            this.Items.Add(new ItemViewModel() { 
                                 Id = Items.Count,
                                 Group = "Group 4", 
                                 LineOne = "runtime sixteen", 
                                 LineTwo = "Nascetur....t pulvinar" });

            var categories = from i in Items
                                     group i by i.Group into category
                                     select new CategoryViewModel(category.Key, category);
            foreach (var category in categories)
            {
               CategoriesAndItems.Add(category);
                foreach (var item in category.Items)
                {
                    CategoriesAndItems.Add(item);
                }
            }
            this.IsDataLoaded = true;

            NotifyPropertyChanged("ItemsView");
        }

Jetzt brauchen wir nur noch eine Listbox und ein Datatemplate pro Datatype. Dummerweise gibt es implizite Styles erst ab Silverlight 4, also helfen wir uns mit TemplateSelector … welchen es auf dem Phone nicht gibt. Also kramen wir noch mal unser Basiswissen raus. TemplateSelector ist ein Control welches Content mit passemdem Template darstellt. Also nur ein ContentControl mit zusätzlicher Logik zur Auswahl des Templates. ContentControl bietet eine Property ContentTemplate und eine Methode, die aufgerufen wird, wenn sich der Content geändert hat. Also führen wir eine kleine Konvention ein, dass das Datatemplate so heißen soll, wie der Type des Contents.

<Application.Resources>
        <DataTemplate x:Key="TestGroupedList.CategoryViewModel">
            <TextBlock Text="{Binding CategoryText}"
                       Style="{StaticResource PhoneTextGroupHeaderStyle}"
                       Margin="0,18,0,0"/>
        </DataTemplate>
        <DataTemplate x:Key="TestGroupedList.ItemViewModel">
            <StackPanel Margin="32,0,0,17"
                        Width="432">
                <TextBlock Text="{Binding LineOne}"
                           TextWrapping="Wrap"
                           Style="{StaticResource PhoneTextExtraLargeStyle}" />
                <TextBlock Text="{Binding LineTwo}"
                           TextWrapping="Wrap"
                           Margin="12,-6,12,0"
                           Style="{StaticResource PhoneTextSubtleStyle}" />
            </StackPanel>
        </DataTemplate>
    </Application.Resources>

Die Selector Klasse selbst ist dann sehr einfach:

public class DataTemplateSelector : ContentControl
{
    protected override void OnContentChanged(object oldContent, object newContent)
    {
        if (newContent == null)
       {
           ContentTemplate = null;
        } else {
            var type = newContent.GetType();
            if (Application.Current.Resources.Contains(type.FullName))
            {
                ContentTemplate = App.Current.Resources[type.FullName] as DataTemplate;
            }
         }
    }
}

Unser XAML für die Listbox sieht so aus:

<ListBox x:Name="MainListBox"
		 Margin="0,0,-12,0"
	                 ItemsSource="{Binding CategoriesAndItems}"
		SelectionChanged="MainListBox_SelectionChanged">
	<ListBox.ItemTemplate>
		<DataTemplate>
			<TestGroupedList:DataTemplateSelector Content="{Binding}" />
		</DataTemplate>
	</ListBox.ItemTemplate>
</ListBox>

In diesem Fall möchte ich nicht das ein Klick auf einen Gruppenheader irgendwas bewirkt, also navigiere ich nur wenn das ausgewählte Item ein ItemViewModel ist. Je nach Anwendungsfall kann ich hier natürlich auch zu Gruppeneinstellungen navigieren o.ä.

 var item = MainListBox.SelectedItem as ItemViewModel;
 if (item != null)
 {
  // Navigate to the new page
  NavigationService.Navigate(new Uri("/DetailsPage.xaml?Id=" + item.Id,
                                                   UriKind.Relative));

   // Reset selected index to -1 (no selection)
    MainListBox.SelectedIndex = -1;
}

Der größte Nachteil dieses Ansatzes soll nicht verschwiegen werden. Da die Auflösung des Templates erst zur Laufzeit stattfindet, kann weder Visual Studio noch Expression Blend eine Vorschau zeigen.

In diesem Fall hatte ich mich entschieden, das die Gruppierung rein für die Darstellung dient, die Logik sollte davon weitgehend unbeeinflusst bleiben. Alternativ hätte ich eine reine Kategorieliste nehmen können und die Items  über HeaderedItemsControl darzustellen. In dem Fall sind Features wie auf- und zuklappen usw. viel einfacher zu implementieren.

Beispielprojekt

Dieses Mal:

Grundkurs funktionale Programmierung mit Scala von Lothar Piepmeyer, Hanser

Recht gut geschrieben, aber für meinen Geschmack ist die Einführung der funktionalen Welt mit Hilfe von Java und der Schwenk im zweiten Teil des Buches auf Scala ein bisschen am Ziel vorbei. Die Sprachkonstrukte von Scala konnten sich m.E. so nicht richtig festigen. Für jemanden, der ohne Wissen über funktionale Sprachen von Java (oder auch C#) kommt, erklärt der Ansatz aber sehr gut funktionale Konstrukte anhand bekannter Mechanismen und deren Vor- und Nachteile. Allerdings hätte das Buch ruhig noch ein bisschen stärker in die Tiefe gehen können.

Fazit:

Ein gutes Buch, aber nicht so richtig für mich geeignet. Von mir 3 von 5 Funktionen.

Dieses Mal ein Review über ein deutschprachiges Buch.

REST und HTTP von Stefan Tilkow, dpunkt.verlag

Wer schon immer mal mehr über Restfull Services wissen wollte, dem sei dieses Buch empfohlen. Der Autor hat ein klare Vorstellung davon, wie REST von der Struktur des HTTP Protokolls profitieren kann. Sehr schön und völlig sprachunabhängig zeigt er mit Hilfe von curl diverse Mechanismen von REST und ihre Verwendung. Die klare Trennung zwischen idempotenten (d.h. beliebig oft abschickbaren) Aufrufen von GET und Methoden die einen Serverzustand verändern, hilft wirklich, wenn man erst mal die Auswirkungen überdenkt.

Leider sind viele der für REST notwendigen Annahmen im .NET Umfeld noch eher selten anzutrefen (ich habe mir noch keine Meinung zum ODATA Framework gebildet, vielleicht wird es ja damit besser)

Fazit:

Ein sehr gut gelungenes Grundlagenbuch. 5 von 5 Requests

I decided to do a short personal Review of all Books I read this year, at least the technical ones. I will alway write the review in the language I read the book.

This time:

jQuery in Action from Bear Bibeault and Yehuda Katz, Manning

I have read the old version and I expect the new version to be even better. A fundamental and well written introduction into the Javascript Framework jQuery. I have used jQuery for over a year now and then, but I learned a tremendous amount of the backgrounds and usage from this book.

Conclusion:

If you want to learn about jQuery, read this book.
Five of Five Stars.

 WP7dev-Cloud-Small

Kinetic Text Intro

Ich bin seit einiger Zeit fasziniert von Kinetic Text Aninmationen. Daher hatte ich für die Usergroup mal ein Demo dazu vorbereitet. Das Intro ist in einer langen Nacht komplett von Hand mit Expression Blend 4 erstellt, inklusive der Word Cloud. Das gesamte Projekt enthält nicht eine einzige Codezeile. Der XAML Sourcecode liegt auf meinem Skydrive unter Kinetictext. Bilder, Video und Sourcecode werden hiermit unter Creative Commons Licence gestellt. Jegliche Form der Verwendung, Bearbeitung und Weitergabe ist ausdrücklich gestattet.

Hier die Materialien zu der Exploration

Leider sind wir mit der Exploration nicht sonderlich weit gekommen. Aber wir haben glaube ich alle viel gelernt. Das (nicht wirklich funktionsfähige) Ergebnis des Abends habe ich mal hier abgelegt.

Weiterführende Links:

Deutschsprachige Einführungsseite von Frank Prengel
http://bit.ly/wp7def
WP7 für Entwickler – Getting Started
http://developer.windowsphone.com/windows-phone-7-series/
WP7-Entwicklung – Doku auf MSDN
http://msdn.microsoft.com/en-us/library/ff402535(VS.92).aspx
WP7-Sessions und Videos von der MIX10
http://live.visitmix.com/Sessions#/tags/Mobile

Are you jealously looking over the fence to Java Enums? Enums in Java are much more than the barely disguised integer constants in C#. In Java the Enum is a special form of a class with a set of fixed instances always inheriting the Enum baseclass They can have local variables and methods.

In C# (or VB so far) enums are much more like strongly typed and named integer subsets in the tradition of C #define. It is possible to give a different base but only different sizes of integer. No way to put any logic onto an enum. No way?

Wrong!

Extension methods to the rescue. I often have Enums coming from a WSDL proxy. As I don’t want the dependency to the webservice to leak into the domain model I convert from and to the internal version. Conversion could be done by a service but I prefer Extension Methods.

Assume the following definition coming from the webservice:

public enum ExternalEnum
{
    Ready,
    SoftwareUpdate,
    HardwareUpdate,
    Error,
    TimeOut
}

As I don’t care for the specific reason the service is unavailable I define:

public enum InternalEnum
{
    DatabaseReady,
    Maintenance,
    ServerError
}

With this extension method defined:

public static class EnumExtensions
{
    public static InternalEnum ToInternalEnum(this ExternalEnum value)
    {
        switch (value)
        {
            case ExternalEnum.Ready:
                return InternalEnum.DatabaseReady;
            case ExternalEnum.HardwareUpdate:
            case ExternalEnum.SoftwareUpdate:
                return InternalEnum.Maintenance;
            case ExternalEnum.TimeOut:
            case ExternalEnum.Error:
                return InternalEnum.ServerError;
            default:
                throw new InvalidCastException("Unknown value for ExternalEnum value " + value);
        }
    }
}

I can convert (and get even Intellisense):

ExternalEnum wsResult = ...;
return wsResult.ToInternalEnum();