ASP.NET Webforms SQLDatasource Querystringparameter Text

Obwohl ich Bücher dazu geschrieben habe, mein Hirn ist leer. Ich habe vergessen wie man mit einem SQLDataSource Control einen Select Parameter per Querystring definiert. Alle Samples nehmen immer nur eine ID und den Typ Int32. Also fürs Archiv: wenn der Query Parameter eine Zeichenkette ist (also String) und man per unscharfen SQL Kommando Like selektieren möchte gilt folgende Lösung.

   1:  WHERE        (dbo.SEM_SEMINARE.sActive = 1 and metatags like '%'+@suche+'%')"
   2:        >
   3:        <SelectParameters>      
   4:        <asp:QueryStringParameter Name="suche"  
   5:                   QueryStringField="suche" Type="String" />
   6:    </SelectParameters>

Warum mache ich das?

Altlasten, eine Website basierend auf ASP.NET 2.0 die die nach modernes UI gehoben werden muss. Also Bootstrap, responsive Design und keine Postbacks. Dazu werden eben Status Informationen in die URL gelegt und nicht in den Viewstate.

x:Bind mit UWP und Performance

Mit Windows Universal Platform Apps wird XAML um eine Funktion erweitert, compiled Binding. Dazu muss man wissen, das in WPF Databinding per Reflection erst zur Laufzeit ausgewertet wird. Bekanntermaßen läuft man dabie leicht in Performanceprobleme rein. Da hört es sich doch super gut an, wenn nun mit X.Bind statt Binding alles schneller wird, oder?

Um diese Frage zu klären, wurde erst eine WPF MVVM Referenzimplementierung codiert und diese dann in einer Windows 10 App nachgebaut. Leider ist der Code nicht so kompatibel wie man glauben würde, so das das WPF Sample nochmals verändert wurde mit dem Ziel möglichst identen Code zu nutzen.

Das Testszenario füllt eine Listview mit einer Million Einträgen und misst die Zeit. In der WPF Anwendung dauert das 14 Sekunden.

image

Ich möchte nicht ausschließen, das in Betrachtungen Performance relevante Fakten nicht korrekt berücksichtigt worden sind und damit die Ergebnisse falsch sein können.

Das Viewmodel implementiert eine Counter Eigenschaft, weil UWP kein Liste.count im compiled Binding unterstützt. Außerdem scheint es in UWP Apps nötig zu sein einer Property vom Typ ObservableCollection manuell das PropertyChangedEvent auszulösen.

Public Class appVM
    Implements INotifyPropertyChanged
    Private _liste As ObservableCollection(Of zeichen)
    Public Property liste() As ObservableCollection(Of zeichen)
        Get
            Return _liste
        End Get
        Set(ByVal value As ObservableCollection(Of zeichen))
            _liste = value
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(NameOf(liste)))
        End Set
    End Property
 
 
    Private _counter As Integer
    Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
 
    Public Property counter() As Integer
        Get
            Return _counter
        End Get
        Set(ByVal value As Integer)
            _counter = value
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(NameOf(counter)))
        End Set
    End Property
End Class
 
Public Class zeichen
    Implements INotifyPropertyChanged
    Private _zeichen As String
    Public Property zeichen() As String
        Get
            Return _zeichen
        End Get
        Set(ByVal value As String)
            _zeichen = value
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(NameOf(zeichen)))
        End Set
    End Property
 
    Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
End Class

Erstaunlicherweise ist .net zu schnell um das Bindung auch im Interface zu aktualisieren. Das heist erst wenn der folgende Code durchgelaufen ist, wird das UI refreshed.

   1:  Class MainWindow
   2:      Public Property l As New appVM
   3:      Private Sub button_Click(sender As Object, e As RoutedEventArgs) Handles button.Click
   4:          textBlock0.Text = Date.Now.ToLongTimeString
   5:          For i = 1 To 1000000
   6:              l.liste.Add(New zeichen With {.zeichen = Date.Now.ToLongTimeString})
   7:              l.counter = l.liste.Count
   8:          Next
   9:          textBlock1.Text = Date.Now.ToLongTimeString
  10:      End Sub
  11:   
  12:      Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
  13:          l.liste = New ObservableCollection(Of zeichen)
  14:          grid1.DataContext = l
  15:          l.liste.Add(New zeichen With {.zeichen = "test"})
  16:          l.counter = l.liste.Count
  17:      End Sub
  18:   
  19:  End Class

 

Im XAML Code wird lediglich eine Listview Control mit einem Datatemplate eingesetzt. Zu Testzwecken wurde mit dem Mode Oneway experimentiert (standard ist twoway) und Binding liste.count verwendet. Beides brachte keine sichtbare Änderung in der Durchlaufzeit.

   1:   <Grid x:Name="grid1">
   2:          <Button x:Name="button" Content="Button" HorizontalAlignment="Left" 
Margin="321,14,0,0" VerticalAlignment="Top" Width="75"/>
   3:          <TextBlock Text="{Binding counter}" HorizontalAlignment="Left" Width="100"
   4:                     TextWrapping="Wrap" VerticalAlignment="Top" Margin="407,18,0,0"/>
   5:          <ListView 
   6:              IsSynchronizedWithCurrentItem ="True"
   7:              ItemsSource="{Binding liste,Mode=OneWay }" x:Name="listView"
   8:              HorizontalAlignment="Left" Height="299" Margin="36,10,0,0" VerticalAlignment="Top" Width="158">
   9:              <ListView.ItemTemplate>
  10:                  <DataTemplate >
  11:                      <Grid>
  12:                          <TextBlock Text="{Binding zeichen,Mode=OneWay}"></TextBlock>
  13:                      </Grid>
  14:                  </DataTemplate>
  15:              </ListView.ItemTemplate>
  16:          </ListView>

 

Identes Szenario in der Windows 10 UPW App. XAML und VB.NET benötigen nun 48 Sekunden und damit mehr als 3x so lange.

image

Völlig überraschend reduziert sich die Zeit bei   Text="{Binding liste.count}"  statt   Text="{Binding counter}" auf 24 Sekunden. Mutmaßlich wird das Binding für den Counter so nur einmal aufgerufen.

Im nächsten Schritt führen wir compiled Bindung ein. Hier gibt es ein paar weitreichende Änderungen

  • Datacontext spielt keine Rolle mehr- Das Viewmodel wird als Property der Page zugewiesen
  • x : Bind ist per Default OneTime
  • Verschachtelte Bindings müssen per x : Datatype auflösbar sein.

Der XAML Code der WUP APP sieht damit wie folgt aus

   1:     xmlns:model="using:App4"
   2:  ...
   3:  <TextBlock Text="{x:Bind l.counter, Mode=OneWay}" HorizontalAlignment="Left" Margin="452,54,0,0" 
   4:                     TextWrapping="Wrap" VerticalAlignment="Top"/>
   5:    <ListView 
   6:         ItemsSource="{x:Bind l.liste,Mode=OneWay}" x:Name="listView"
   7:         HorizontalAlignment="Left" Height="299" Margin="36,10,0,0" VerticalAlignment="Top" Width="158">
   8:     <ListView.ItemTemplate>
   9:        <DataTemplate x:DataType="model:zeichen">
  10:            <Grid>
  11:              <TextBlock Text="{x:Bind zeichen, Mode=OneWay}"></TextBlock>
  12:            </Grid>
  13:       </DataTemplate>
  14:   </ListView.ItemTemplate>
  15:  </ListView>

 

Die Durchlaufzeit des kompilierten XAML Databinding Beispiels liegt nun bei 23 Sekunden und damit bei rund 50% des normalen Bindings. Allerdings noch immer deutlich über den Werten von WPF (14 Sekunden). Dazu kommt das sich X.Bind mit seinen default Wert überraschend verhält. Auch die Collection, die sich nicht aktualisiert, ist ein unerwartetes Ergebnis und Effekt des Kompilier Vorganges. Alternativ lässt sich mit Bindings.Update eine Aktualisierung erzwingen, was ich aber als seltsam im Kontext von MVVM empfinde. Zusätzlich war es schwierig Programmierfehler zu finden. Normale Binding Fehler werden im Output Window von Visual Studio angezeigt. Für compiled Bindings suche ich noch nach derartiger Hilfe. Was mich zusätzlich verwundert, ist das eigentlich eine UWP App native Code enthalten sollte und damit meines Erachtens nach schneller als eine .net JIT Optimierung sein sollte. Dieser Blog Artikel liefert also mehr Fragen als Antworten.

Nachtrag 1: Aufgrund erster Diskussionen beide Anwendungen direkt ohne Visual Studio gestartet. WPF: 12 Sekunden –70MB Ram im Taskmanager. WUP 10 21 Sekunden – 315 MB.

F12 XAML Debug Developer Tools

Der Betreff ist frei erfunden. Es gibt keine F12 Taste für XAML, nein es ist viel besser. Mit Visual Studio 2015 kann man WPF Anwendungen und den darin enthalten XAML Code zur Laufzeit analysieren. Dabei muss man nicht mal den Quellcode besitzen. Das geht mit jeder beliebigen Anwendung und dem Visual Studio enthalten Tools:  Live Views XAML – Live Visual Tree und Live Property Explorer.

Wenn eine WPF Anwendung läuft, kann sich der Visual Debugger an den laufenden Prozess hängen (Debuggen – an den Prozess anhängen oder STR ALT P). WPF Anwendungen sind leicht zu erkennen, da sie vom Typ managend Code sind.

image

Im Eigenschaftsfenster visuelle Echtzeitstruktur (visual Tree) ist die XAML Struktur zu erkennen. Ganz ähnlich wie im Browser DOM Explorer lässt sich per Pfeil in der WPF Anwendung das UI Element auswählen.

image

Zusätzlich lassen sich live im weiteren Eigenschaftsfenster Echtzeit Eigenschafts Explorer sämtliche Properties der deklarativen UI ändern. Hier wurde die Beschriftung (Caption) ersetzt.

image

Für die neuen Windows Universal Plattform Apps ist die Vorgehensweise etwas anders, aber im Ergebnis gleich überzeugend. Dazu wird in Visual Studio über andere Debug Ziele (other debug tragets)- ein vorhandenes installiertes App-Paket ausgewählt. Die App darf nicht laufen.

image

Da UWP kein managend sondern native Code ausführt, muss die Option systemeigen (native only) gewählt werden. In diesem Beispiel nehmen wir uns die Windows 10 Wetter App vor um zu erforschen wie der XAML Code aufgebaut ist

image

Die App Startet und Visual Studio zeigt den visual XAML Tree. Hier im Bild mit ausgewählter Layout Adorner Funktion (zweite Icon von links).

image

Auf die neuen visuellen WPF Debugging Funktionen bin ich gestoßen im Rahmen der Vorbereitung meiner ADC WPF Session.

besser lesen im Browser Lesemodus

Wir werden älter oder die Buchstaben kleiner. Egal mit welcher Perspektive, Microsoft hat seit drei Jahren für uns eine echte Innovation, den Lesemodus oder auch Reading View genannt. Dabei kann der Benutzer eine Website in einem auf den Text fokussierten lesefreundlichen Modus konsumieren.

Die Leseansicht wurde mit IE11 aus Windows 8, dem METRO Browser eingeführt. Eine eigene Logik erkennt passende Websites und blendet in der Adressleiste ein Buch Icon ein, wenn der Inhalt geeignet erscheint.

image

Danach fokussiert der Browser die Darstellung auf das Wesentliche und blendet kleine Bilder wie Werbung oder Menüs aus.

Der neue Edge Browser und der Windows 8.1 phone Browser unterstützen diese Ansicht ebenfalls. Sogar Mozilla Firefox zieht in der Version 40 nach. Webdesigner sollte ein paar Regeln kennen um davon bestmöglichen Nutzen ziehen zu können.

Grundsätzlich sollen mindestens 700 Zeichen auf der Website sein. Dazu gehören folgende Metatags ohne die z.B. der Windows Phone Browser die Darstellung verwehrt. Die Inhalte werden dann im Lesemodus an definierter Stelle eingeblendet, außer Title.

   1:  <title>Lesemodus</title>
   2:  <meta name="displaydate" content="muss kein Datum sein oben">
   3:  <meta property="og:site_name" content="ppedv AG">
   4:  <meta name="copyright" content="copyright am Ende">

Die Überschrift wird aus dem ersten H1 Element ausgelesen. Erst der darauf folgende Text, idealerweise in ein P Element gepackt, wird dann alternativ formatiert dargestellt. Die Schriftgröße und Art wird vereinheitlicht.

readingview1

readingview2

Bilder müssen  >= 400 px mit einem Verhältnis >= 1/3 und =< 3.0 sein. Andernfalls werden diese nicht angezeigt. Laut Dokumentation sollte man Bilder in  figure Element schachteln und per figcaption beschreiben. Der Edge Browser zeigt dann in meinen Versuch kein Bild mehr an.

Im Standardfall wird das erste Bild als dominantes Image bezeichnet und über den Text dargestellt, was auf dem Smartphone sehr gut aussieht. Im Screenshot zu erkennen ist auch der Autor und Datum aus den Metatags.

lesemodus3

Alle weiteren Bilder im Textfluss, die obige Größenanforderungen erfüllen, werden im Fließtext dargestellt.

image

Im Screenshot ist auch der Copyright Hinweis am Ende zu erkennen.

Der Lesemodus ist kein Standard, Mozilla interpretiert die Inhalte anders. Auch werden in den Test Bilder nicht nachvollziehbar ausgeblendet. Versuche mit existierenden Websites legen den Schluss nahe, das es wesentlich mehr Regeln im Browser gibt nach denen eine Darstellung im Lesemodus erfolgt.

image

Die Kurs Websites der ppedv Schulungen kommen aus dem gleichen Template und werden Datengebunden gefüllt und trotzdem unterschiedlich dargestellt.

image

Ich werde an dem Thema dranbleiben, weil es speziell für mobile Darstellung ein echter Gewinn an Usability ist.

Nachtrag: dieser Blogartikel ist aus unerfindlichen Gründen nicht für den Reading View geeignet.

CSS Klassen Naming Schema

Durch meine Arbeit mit Material Design Lite bin ich über das opulente CSS Klassen Konzept gestolpert. Es ist ziemlich aufwändig die CSS Klassen zu tippen und Visual Studio Intellisense kann basierend auf diesem Schema nicht wirklich hilfreich sein.

Zwei Beispiele sollen dies erläutern.

   1:  <table class="mdl-data-table mdl-js-data-table mdl-data-table--selectable mdl-shadow--2dp">
   2:   
   3:  th class="mdl-data-table__cell--non-numeric">Material</th>

 

Jedenfalls haben ich in diesem Kontext gelernt, das es ein Namensschema BEM gibt. In HMTL für Block-Element-Modifier.

Da CSS3 keine Namensräume kennt, stellen die MDL Entwickler das Präfix mdl- voran. In Anbetracht der schieren Fülle der Klassennamen tippt man sich einen Ast- hier mdl-textfield bis man überhaupt an der richtigen Stelle steht. Dazu kommt das man in der Regel immer zwei CSS Klassen Minimum benötigt. Eine für Design und eine fürs JavaScript.

image

BEM definiert einen Block, z.B. die HTML Tabelle, ein Menü oder Tab Bereich. Hier als Tabelle data-table genannt.

In der nächsten Hierarchiestufe findet sich das Element, getrennt mit einem doppelten Unterstrich. Beispiel ist data-table__cell oder textfield__input.

Da der Bindestrich schon für zusammengesetzte Worte genutzt wird (data-table), kommt ein doppelter Bindestrich für eine nächste Hierarchiestufe Modifier zum Einsatz. Obig wird die data-table als –selectable definiert oder die Schattentiefe.

Akademisch ist das eine gute Idee. In der Praxis ist der Schreibaufwand erheblich. Darüber hinaus sind die gewählten Namen (textfield, data-table, --floating-label ) selten intuitiv. Im Vergleich zu Bootstrap ergibt sich eine relevant geringere Produktivität.

Visual Basic 14 Zeichenketten

Wenn ich schon dabei bin, sämtliche Neuerungen zu Visual Basic 14 (in Visual Studio 2015) zu erläutern, dann auch noch schnell die Zeichenketten.

Seit langer Zeit gibt es in VB.NET XML Literals, die wie aus ASP.NET Webforms geklaut aussehen. Neben dem mehrzeiligen XML Code, kann man auch Ausdrücke injizieren.

   1:    Dim a As Integer = 42
   2:    Dim xml = <xml>
   3:                        <node>
   4:                            <%= a %>
   5:                        </node>
   6:                    </xml>
   7:   text1.Text = xml

In Kombination mit LINQ sind da sehr abgefahrene Zeilen Code möglich. C# Programmierer konnten das nicht und platzten vor Neid. Vermutlich deshalb wurde XML auch zusehend ignoriert und durch JSON ersetzt. VB.NET zieht nach und kann nun Strings mehrzeilig und mit Ausdrücken.

   1:    text1.Text = $"Hello
   2:                               world
   3:          {a}"

Das $ Zeichen ist nur nötig, wenn man Ausdrücke per geschweifter Klammer injiziert.

Der Zeilenumbruch wird als vbCRLF in den String eingefügt, genauso wie Leerzeichen.

image

Das war auch schon das Ende der zweiteiligen Reihe “Neue Sprachfeatures in VB.NET 14”

Visual Basic .net 14 nameOf

Mit .net 4.6 ist auch Visual Basic in einer neuen Version angelangt. Gemeinsam mit C#6 ist das neue Sprachfeature nameOf. Was hat es nun damit auf sich und gibt es da nicht schon?

Kurz gesagt liefert NameOf den Namen einer Klasse als String ohne Reflection bemühen zu müssen. Da dies auf Compiler Ebene geschieht, ohne Performance Nachteile.

Der Name einer Eigenschaft wird z.B. in jeder MVVM Property benötigt um die Notification an das User Interface auszulösen. Folgender Code wird jeden View Model Programmierer täglich Brot sein, wenn er die Klasse per Implements INotifyPropertyChanged mit dem Interface versieht.

   1:  Private newPropertyValue As String
   2:      Public Property NewProperty() As String
   3:          Get
   4:              Return newPropertyValue
   5:          End Get
   6:          Set(ByVal value As String)
   7:              newPropertyValue = value
   8:              RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("NewProperty"))
   9:          End Set
  10:  End Property
  11:   
  12:  Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged

Das Code Schnippsel wurde mit Visual Studio 2015 im Code Editor per prop + TAB +TAB erstellt. Ich würde schwören das in früheren Versionen ein Unterstrich für die private interne Eigenschaft verwendet wurde.

In der Regel wird man in den VM Klassen eine Abstraktionsfunktion finden ala

   1:   Protected Sub OnPropertyChanged1(propertyName As String)
   2:          RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
   3:   End Sub

So muss nur noch OnPropertyChanged1 mit dem Namen der Eigenschaft als Parameter aufgerufen werden. Logik in Hochkommas ist allerdings schon seit SQL fehleranfällig.

Mit Visual Studio 2012 kommt ein Compiler Attribut, das den Namen eigenständig auflöst: Callermembername

   1:  Protected Sub OnPropertyChanged(<CallerMemberName> Optional propertyName As String = Nothing)
   2:          RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
   3:  End Sub

 

In der Eigenschaft der Klasse reicht dann ein einfaches onPropertyChanged() (statt Zeile 8) und alles ist gut. Einziger Nachteil, das geht nur innerhalb von Funktionsparametern.  Es kann sein, das man im Viewmodel aus einer Zuweisung eines Wertes das PropertyChanged Event eines anderen Propertys auslösen möchte. Jedenfall gibt es nun NameOf, das diese Flexibilität auch wieder durch den Compiler bringt.

   1:  OnPropertyChanged1(NameOf(NewProperty))

Material Design Farbpalette

Die UI Designsprache Material Design aus dem Haus Google, kommt mit unglaublichen 19 benannten Farben aus. Mehr sind nicht erlaubt. Für den Einsatz in Websites wird das Framework Material Design Lite (MDL) angeboten. Auf dessen Website finden sich als Farbpaletten Helfer der Farbfächer.

image

Damit wählt der Designer eine Primär Farbe und eine Sekundärfarbe. Die Primärfarben finden sich im äußeren Ring, die Akzentfarbe im inneren, etwas dunkleren Ring. Das Ergebnis wird exemplarisch rechts daneben dargestellt.

Die genauen Specs von Material Design erlauben abweichend davon mehrere Schattierungen innerhalb eines Farbtones. Diese sind je nach Helligkeit von 50 (hell) bis 900 (dunkel) durchnummeriert. Akzentfarben wird ein A vorgestellt.

image

Es wird empfohlen mit dem 500er Wert von hier z.B. Orange zu starten bei der Nutzung als Primärfarbe.  Der untere Bereich der Farbtabelle definiert vier Akzentfarben. Diese werden nach kontrastgesichtspunkten zur Primärfarbe gewählt. Umgesetzt auf Bild 1 sind das Indigo 500 und Orange A200. Bei der Nutzung als Statusbar soll man einen dunkleren 700er Ton ansetzen.

image

Bei der Nutzung des obigen Farbrades schlagen die  Google Developer anschließend einen Link  vor um das css einzubinden.

<link rel="stylesheet" href="https://storage.googleapis.com/code.getmdl.io/1.0.0/material.indigo-orange.min.css" />

Das kann man mögen und auch mit dem Argument Content Delivery Network verargumentieren, allerdings weis dann Google auch von jeder Website und jedem Benutzer. Von diesen Daten lebt die Company.  Meine Empfehlung lautet, die Style Klassen manuell in ein auf dem eigenen Webserver lokal liegende CSS einzubinden.

Eine Session zum Thema finden Sie auch auf der Jquery Berlin.

Material Design Lite UX Framework

UI Designer folgen seit einigen Jahren dem Flat Ansatz. Google bringt eine neue einfach Design Sprache -Material Design- um seine Android Plattform zu gestalten. Relativ neu findet dieses Konzept auch seinen Weg ins Web. Dabei stehen von den Erfindern gleich drei Frameworks zur Verfügung: Polymer, Angular Material und jetzt neu Material Design Lite (MDL).

MDL adressiert die einfache Website und kann am ehesten als Wettbewerber zu Boostrap betrachtet werden.  Erste Web Seiten mit den Material Templates finden sich bereits in produktiver Nutzung.

image

Man erkennt die wenigen aber kräftigen Farben. Information wird in sogenannte Cards gruppiert, die sich optisch durch einen umlaufenden Schatten abheben. Google nennt das Paper Design.

Die Installation des Frameworks erfolgt per Bower oder npm über die Visual Studio 2013 Developer Command Shell.

npm install material-design-lite –save

Die wesentlichen Scripts und Styles finden sich dann im Unterverzeichnis node_modules

image_thumb

Ich halt es mit den Galliern und ignorier die wachsende Besatzung der Welt mit node.js. IIS Express ist auch gut für mich.

In der HTML Seite oder bei ASP.NET Webforms in der Masterpage, werden die Referenzen auf material.css und js gesetzt. Zusätzlich werden noch Icons benötigt, die man lokal im Webserver Verzeichnis speichern oder verlinken kann.

   1:   <link href="node_modules/material-design-lite/material.css" rel="stylesheet" />
   2:   <script src="node_modules/material-design-lite/material.js"></script>
   3:  <link rel="stylesheet" href="//fonts.googleapis.com/icon?family=Material+Icons">

 

Das Seitenlayout teilt sich in ein 12 Spalten Grid, basierende auf den üblichen DIV. Alle CSS Klassen beginnen mit mdl- . Eine Seite beschreibt sich mit per   <div class="mdl-layout mdl-js-layout ">. Die Spalte über die halbe Seite mdl-cell mdl-cell--6-col.

In der Regel startet der Web Designer mit der Benutzerführung, also dem Menü. Für dieses existieren zwei Varianten, Der Hyperlink basierte Navigation Header und dem Tab Layout das per #Hash Single Page Navigation ausführt.

   1:  <header class="mdl-layout__header is-casting-shadow">
   2:      <div class="mdl-layout__header-row">
   3:          <!-- Title -->
   4:          <span class="mdl-layout-title">ppedv</span>
   5:          <!-- Add spacer, to align navigation to the right -->
   6:          <div class="mdl-layout-spacer"></div>
   7:          <div class="mdl-textfield mdl-js-textfield mdl-textfield--expandable
   8:            mdl-textfield--floating-label mdl-textfield--align-right">
   9:              <label class="mdl-button mdl-js-button mdl-button--icon"
  10:                     for="waterfall-exp">
  11:                  <i class="material-icons">search</i>
  12:              </label>
  13:              <div class="mdl-textfield__expandable-holder">
  14:                  <input class="mdl-textfield__input" type="text" name="sample"
  15:                         id="waterfall-exp" />
  16:              </div>
  17:          </div>
  18:   
  19:          <div class="mdl-layout-spacer"></div>
  20:          <!-- Navigation. We hide it in small screens. -->
  21:          
  22:              <nav class="docs-navigation mdl-navigation">
  23:                  <a class="mdl-navigation__link " href="HtmlPage1.html">ppedv</a>
  24:                  <a class="mdl-navigation__link" href="news.html">news</a>
  25:              </nav>
  26:          
  27:      </div>
  28:  </header>

 

In diesem Beispiel wurde auch noch ein Eingabefeld (Suchfeld) im Header platziert. Dieses erweitert sich automatisch, wenn es den Fokus erhält.

image

Das Menü verhält sich bei kleineren Screenformaten nicht wie von Bootstrap responsive gewohnt. Es verschwindet ganz und übrig bleibt, die sogenannte Hamburger Schaltfläche.  Dazu muss aber ein extra Menü für kleine Bildschirmgrößen definiert werden. Dies wird als Drawer bezeichnet.

   1:  <div class="mdl-layout__drawer">
   2:      <span class="mdl-layout-title">Title</span>
   3:      <nav class="mdl-navigation">
   4:          <a class="mdl-navigation__link" href="">Link</a>
   5:          <a class="mdl-navigation__link" href="">Link</a>
   6:          <a class="mdl-navigation__link" href="">Link</a>
   7:          <a class="mdl-navigation__link" href="">Link</a>
   8:      </nav>
   9:  </div>

 

Das Drawer Menü klappt in jedem Format von Links in den sichtbaren Bereich.

image

Im nächsten Schritt werden Daten angezeigt. Dafür kommt eine HTML Tabelle zum Einsatz, die per mdl-grid und mdl-cell DIV platziert werden. Von Bootstrap oder auch Jquery mobile bekannte Badges, finden sich auch in MDL. Die class="mdl-badge" nutzt das Attribut data-badge="4” um einem Text ein optisch per Kreis markierte Infozahl zu verpassen.

Datenlisten haben oft auch die Möglichkeit, neue Datensätze zu erfassen. Der HTML Button wird dabei zu einem Kreisrunden Button mit speziellen Hover Effekten und Icon Symbolik.

   1:  <button class="mdl-button mdl-js-button mdl-button--fab mdl-button--colored">
   2:      <i class="material-icons">add</i>
   3:  </button>

 

Natürlich gibt es auch rechteckige Buttons, die denen von Bootstrap ähneln.

image

Die Google Developer haben sich offensichtlich große Mühe gegeben auch für Screenreader (Stichwort Blinde Nutzer) korrekten HTML Code zu unterstützen.

 

   1:  <table class="mdl-data-table mdl-js-data-table mdl-data-table--selectable mdl-shadow--2dp">
   2:      <thead>
   3:          <tr>
   4:              <th class="mdl-data-table__cell--non-numeric">Firma</th>
   5:              <th>Ort</th>
   6:              <th>Plz</th>
   7:          </tr>
   8:      </thead>
   9:      <tbody>
  10:          <tr>
  11:              <td class="mdl-data-table__cell--non-numeric">
  12:                  <div class="mdl-badge" data-badge="4">ppedv</div>
  13:              </td>
  14:              <td>Burghausen</td>
  15:              <td>84489</td>
  16:          </tr>
  17:          <tr>
  18:              <td class="mdl-data-table__cell--non-numeric">ppedv gmbh</td>
  19:              <td>Wien</td>
  20:              <td>1150</td>
  21:          </tr>
  22:          <tr>
  23:              <td class="mdl-data-table__cell--non-numeric">Microsoft</td>
  24:              <td>Unterschleißheim</td>
  25:              <td>88885</td>
  26:          </tr>
  27:      </tbody>
  28:  </table>

Optisches Highlight sind Formulare bzw das Verhalten der Eingabefelder. Google Maps Nutzer kennen das schon. Ein INPUT Element wird nur durch einen Unterstrich markiert. Der Labeltext befindet sich auf der Linie. Wenn die Textbox en Fokus erhält wandert animiert, das Label darüber und wird kleiner.

image

image

image

 

   1:  <div class="mdl-cell mdl-cell--2-col">
   2:      <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label textfield-demo">
   3:          <input class="mdl-textfield__input" type="text" pattern="-?[0-9]*(\.[0-9]+)?" id="sample4" />
   4:          <label class="mdl-textfield__label" for="sample4">Number...</label>
   5:          <span class="mdl-textfield__error">Input is not a number!</span>
   6:      </div>
   7:  </div>

 

Dieses Element der UI Sprache, den etwas dickeren farbigen Unterstrich, findet man auch in der Tab Komponente wieder.

image

Die Tabs werden mit mdl-tabs__tab deklariert. Die Steuerung erfolgt per Href und #Hash ID’s. Leider sind deshalb auch keine Hyperlinks möglich, weil es sich um eine reine In-Page Navigation handelt.

Je Tab wird ein Panel benötigt, mit der zum Tab passenden ID.

   1:  <div class="mdl-tabs mdl-js-tabs mdl-js-ripple-effect">
   2:      <div class="mdl-tabs__tab-bar">
   3:          <a href="#panel1" class="mdl-tabs__tab is-active">IT Pro</a
   4:          &lt;a href="#panel2" class="mdl-tabs__tab">Developer</a>
   5:          <a href="#panel3" class="mdl-tabs__tab">Soft Skill</a>
   6:      </div>
   7:      <div class="mdl-tabs__panel is-active" id="panel1">
   8:          <ul>
   9:              <li>SQL Server</li>
  10:              <li>IIS</li>
  11:              <li>Windows</li>
  12:              <li>Exchange</li>
  13:              <li>Lync/Skype</li>
  14:              <li>TMG</li>
  15:          </ul>
  16:      </div>
  17:      <div class="mdl-tabs__panel" id="panel2">
  18:          <ul>
  19:              <li>ASP.NET</li>
  20:              <li>Webforms</li>
  21:              <li>Angular JS</li>
  22:              <li>WPF</li>
  23:          </ul>
  24:      </div>
  25:      <div class="mdl-tabs__panel" id="panel3">
  26:          <ul>
  27:              <li>Project</li>
  28:              <li>SCRUM</li>
  29:          </ul>
  30:      </div>
  31:  </div>

 

Weil das optisch ein echter Hingucker ist, wünschen sich den Unterstrich manche auch für die Hyperlinks im Navigation Menü. Technisch gesehen ist das nicht schwierig, erfordert aber eine CSS Klasse die dem aktiven Navigation Link zugewiesen werden muss,

In obigen Screenshot  ist das umgesetzt (ppedv news). Die Idee dafür und der CSS Code stammt von der MDL Website. Auch dort wird der aktive Bereich so angezeigt, obwohl eigentlich nicht so vorgesehen.

image

image

Moderne Websites haben heute gerne überdimensionale Fuß Bereiche. Ursprünglich für Google Search Optimierung (SEO) erdacht,  bringt man da heute eine Art alternatives Menü unter. MDL kennt zwei Varianten. Die einzeilige mit class=mdl-mini-footer und einer Linkliste per UL (mdl-mini-footer—link-list). Die zweite Variante ist mehrzeilig und mächtig.

   1:  <footer class="mdl-mega-footer">
   2:      <div class="mdl-mega-footer--middle-section">
   3:          <div class="mdl-mega-footer--drop-down-section">
   4:              <input class="mdl-mega-footer--heading-checkbox" type="checkbox" checked>
   5:              <h1 class="mdl-mega-footer--heading">IT Pro</h1>
   6:              <ul class="mdl-mega-footer--link-list">
   7:                  <li><a href="#">IIS</a></li>
   8:                  <li><a href="#">Windows Server</a></li>
   9:                  <li><a href="#">SQL Server</a></li>
  10:                  <li><a href="#">Exchange</a></li>
  11:              </ul>
  12:          </div>
  13:          <div class="mdl-mega-footer--drop-down-section">
  14:              <input class="mdl-mega-footer--heading-checkbox" type="checkbox" checked>
  15:              <h1 class="mdl-mega-footer--heading">Dev </h1>
  16:              <ul class="mdl-mega-footer--link-list">
  17:                  <li><a href="#">Angular.js</a></li>
  18:                  <li><a href="#">ASP.NET</a></li>
  19:                  <li><a href="#">HTML5</a></li>
  20:                  <li><a href="#">WPF</a></li>
  21:              </ul>
  22:          </div>
  23:          <div class="mdl-mega-footer--drop-down-section">
  24:              <input class="mdl-mega-footer--heading-checkbox" type="checkbox" checked>
  25:              <h1 class="mdl-mega-footer--heading">Managment</h1>
  26:              <ul class="mdl-mega-footer--link-list">
  27:                  <li><a href="#">Scrum</a></li>
  28:                  <li><a href="#">Project</a></li>
  29:                  <li><a href="#">Power Pivot</a></li>
  30:                  <li><a href="#">Sharepoint</a></li>
  31:               </ul>
  32:          </div>
  33:          <div class="mdl-mega-footer--drop-down-section">
  34:              <input class="mdl-mega-footer--heading-checkbox" type="checkbox" checked>
  35:              <h1 class="mdl-mega-footer--heading">FAQ</h1>
  36:              <ul class="mdl-mega-footer--link-list">
  37:                  <li><a href="#">Questions</a></li>
  38:                  <li><a href="#">Answers</a></li>
  39:                  <li><a href="#">Contact us</a></li>
  40:              </ul>
  41:          </div>
  42:      </div>
  43:      <div class="mdl-mega-footer--bottom-section">
  44:          <div class="mdl-logo">Title</div>
  45:          <ul class="mdl-mega-footer--link-list">
  46:              <li><a href="#">Help</a></li>
  47:              <li><a href="#">Privacy &amp; Terms</a></li>
  48:          </ul>
  49:      </div>
  50:  </footer>

 

image

Man fragt sich was die Checkboxen im HTML Code sollen? Diese dienen dazu bei Small Devices (Smartphone) die Bereiche aufklappbar darzustellen.

image

Fazit:

Was soll man dazu sagen? Noch ein UI Framework. dazu recht unausgegoren aber mit modernen Style. Alternative sind Modern UI Bootstrap Themes, die aber nicht ganz die Funktion bringen können.

IIS zeigt Error 500 statt 404

Neuere Versionen des IIS zeigen im Fiddler Proxy log eine 500er Meldung für fehlende Elemente wie Bilder, CSS oder js. Das macht das Finden von broken Links unmöglich.

Lösung in Web.config folgenden Code ergänzen.

   1:  <configuration>
   2:   
   3:    <system.webServer>
   4:      <httpErrors errorMode="Detailed" />
   5:    </system.webServer>
   6:  </configuration>
Training, Schulung, August Aktion

Month List