Windows 8 CarouselPanel

Ein Karussell dreht sich. Ein WinRT Steuerlement laesst vermuten das es sich um ein Liste mit drehenden 3D Darstellung handelt. Nicht in Windows 8 Consumer Preview. Ursprünglich wurde das Control entwickelt für die Combobox, um am Ende der Liste wieder am Anfang zu beginnen. Das ganze funktioniert aber nun auch mit typischen Listen. <ListBox x:Name="listbox1" DisplayMemberPath="name" Height="300" Width="600"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <CarouselPanel /> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> </ListBox> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Die Liste ( hier weiß) beginnt nach Vanessa wieder mit Hannes, scrollt also unendlich von unten nach oben. Wenn man nun andere Listen nimmt und das Scrollen Horizontal machen möchte, geht dies z.B, mit einem Gridview und einem Stackpanel. <GridView x:Name="gridview1" HorizontalAlignment="Left" Margin="283,17,-813,0" VerticalAlignment="Top" Width="721" Height="237"> <GridView.ItemTemplate> <DataTemplate> <Border CornerRadius="5" > <TextBlock Text="{Binding name}"> <TextBlock.RenderTransform> <CompositeTransform Rotation="90"/> </TextBlock.RenderTransform> </TextBlock> </Border> </DataTemplate> </GridView.ItemTemplate> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <!--<CarouselPanel CanHorizontallyScroll="true"/>--> <StackPanel Orientation="Horizontal"></StackPanel> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> </GridView> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }   Wie man am auskommentierten Block erkennen kann, könnte das WinRT CarouselPanel zwar Horizontales Scrollen- als Attribut - aber zur Laufzeit gibt's einen Fehler. Ich vermute, das hier der .NET Part einfach noch nicht fertig auscodiert ist. Aber die letzte Windows 8 Beta steht ha schon in den Startlöchern.

Windows 8 Search Contract

Mit den Windows 8 Contracts, können Anwendungen oder das Betriebssystem mit einer App kommunizieren, auch wenn diese nicht läuft. So kann der Benutzer über dem Charme Suchdialog in verschiedenen APPs suchen. Wie üblich muss zunächst im Manifest die Declaration search aktiviert werden. Dann wird eine neue Seite mit dem Template “Search Contract” erstellt. \ Dies erzeugt die Page die gestartet wird, wenn die APP per Search aktiviert wird. Gesteuert wird dies in der app.xaml.vb.  mit dem Event OnSearchActivated. Der folgende Codeblock wird automatisch vom “Search Contract” Template mit erzeugt. Protected Overrides Sub OnSearchActivated(ByVal e As Windows.ApplicationModel.Activation.SearchActivatedEventArgs)        SearchResultsPage1.Activate(e.QueryText)        'TODO: Move the following code to OnLaunched to speed up searches when your        'application is already running:        AddHandler Windows.ApplicationModel.Search.SearchPane.GetForCurrentView().QuerySubmitted,            Sub(sender, queryArgs)                SearchResultsPage1.Activate(queryArgs.QueryText)            End SubEnd Sub In meinem Beispiel baue ich allerdings eine davon unabhängige Suche in die APP ein. Da eine APP durchaus mehrere Listen darstellen kann, sollte in diesen auch gesucht werden können. Hier wird vom ppedv Twitter Account die Neuigkeiten geladen. Dazu kommt der SyndicationClient zum Einsatz. Alles in WinRT und .NET vorhanden und mit einem Vierzeiler an VB Code zu erledigen. Private Async Sub UserControl31_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded  Dim uri As Uri = New Uri("http://twitter.com/statuses/user_timeline/ppedv.rss")  Dim clt As SyndicationClient = New SyndicationClient() feed = Await clt.RetrieveFeedAsync(uri)  listview1.ItemsSource = feed.ItemsEnd Sub Die Darstellung erfolgt im WinRT Listview Control. In diesem soll dann per Search Charme gesucht werden können. Bereits verwendete Suchphrasen werden sogar schon seitlich vorgeschlagen. Die Anwendung muss nur das Event der auftauchenden SearchPane abonnieren, hier mit onQuerySubmitted.  In den Feed Elementen wird dann per LINQ eine Abfrage durchgeführt und dem Listview wiederum zugewiesen. Dim feed As SyndicationFeed    WithEvents sp As SearchPane = SearchPane.GetForCurrentView    Public Sub OnQuerySubmitted(ByVal sender As Object, ByVal args As SearchPaneQuerySubmittedEventArgs) Handles sp.QuerySubmitted         Dim q = From i In feed.Items                      Where i.Title.Text.ToLower.Contains(args.QueryText.ToLower)                            Select i        listview1.ItemsSource = q        TextBox1.Text = "Suche nach " & args.QueryText    End Sub

Windows 8 Kontakte

Das Konzept von Share by Contract in Windows 8 findet sich auch in der Verwaltung von Kontakten wieder. Es macht einfach Sinn einen Adressverwaltung zu haben und nicht zehn in Facebook, Outlook, Twitter,Messenger und co. Eine WinRT METRO styled App, kann als Adressquelle dienen (also doch mehr als eine) oder diese konsumieren. Wer in den Manifest Einstellungen den Contact Picker auswählt, will ein Adressanbieter werden. Das ist nicht Thema in diesem Blog Eintrag. Windows 8 bietet ähnlich einem FilePicker einen ContactPicker, der es erlaubt einen oder mehrere Kontakte auszuwählen. Alles was als Kontakt Quelle per Declaration spezifiziert ist, taucht dann auf. Falls nur eine METRO App mit Contact Contract auf dem Systeminstalliert ist,wird dieser Dialog übersprungen und Benutzer befindet sich gleich in der Contacts APP. Es gibt aktuell kein SDK Beispiel für C# oder VB.NET nur für JavaScript. Der nötige Code ist aber einfach, Man kann den Benutzer einen oder viele Kontakte auswählen lassen, Dim picker As New ContactPicker . Dim rawContacts As IEnumerable = Await picker.PickMultipleContactsAsync() .. picker.PickSingleContactAsync()   .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }   Auf einige Eigenschaften wie Name kann man direkt zugreifen. Private Async Sub Button_Click_1(sender As Object, e As RoutedEventArgs) Dim picker As New ContactPicker Dim rawContacts As IEnumerable = Await picker.PickMultipleContactsAsync() Dim contacts = rawContacts.Cast(Of ContactInformation)() For Each contact In contacts ... contact.Name Next End Sub .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }   Andere Eigenschaften wie Locations, PhoneNumbers oder eMails sind als Listen angelegt. er Index kann dann auf das eigentliche Objekt contact.PhoneNumbers(0).Value zugegriffen werden. Im Kontakte Dialog werden diese n Telefonnummern verwaltet. Im Code kann auf die Eigenschaft Name und Value zugegriffen werden. Wer noch mehr braucht, weil er z.B. spezielle Kundeninformationen für eine Geschäftsanwendung wie Umsatz oder Rabatt hinterlegen möchte, kann dafür die Custom Fields nutzen.

Windows 8 Settings Pain

Nein - richtig gelesen, kein Druckfehler. Die Verwendung der WinRT Standard Settings Pane ist eine Qual. Die Designer dieser Funktion haben XAML Funktionen weitest gehend außer acht gelassen. Obwohl Standard, fehlen die Wizards oder Templates um so einen Settings Dialog zu erstellen. Einstellungen zum Programm sollen über den Settings Dialog, erreichbar per Charme, vorgenommen werden. Dieser Standard Dialog ist aber ein Windows WinRT System Dialog, den man nicht per XAML erweitern kann. Möglich sind auch nur neue HyperlinkButtons. Grundsätzlich ist es egal, an welcher Stelle des Codes man den Settings Dialog um Funktionen erweitert. Wenn man das in der app.xaml.vb tut,gilt dies natürlich für die gesamte App. Man muss das Event belegen, das den Start der Settings signalisiert (Commandsrequested) und dort neue Settingscommands hinzufügen. Protected Overrides Sub OnLaunched(args As LaunchActivatedEventArgs) ... AddHandler SettingsPane.GetForCurrentView().CommandsRequested, AddressOf OnSettingsRequest .... Protected Sub OnSettingsRequest(sender As SettingsPane, args As SettingsPaneCommandsRequestedEventArgs) Dim h As New SettingsCommand("HilfeID", "Hilfe", New UICommandInvokedHandler(AddressOf HilfeFunktion)) args.Request.ApplicationCommands.Add(h) End Sub Private Async Function HilfeFunktion() As Task Dim msg As MessageDialog = New MessageDialog("Bing hilft immer") Await msg.ShowAsync() End Function .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }   Das ist natürlich recht unbefriedigend. Per XAML kann ein User Control erstellt werden, das dann als erweiterter Settingsdialog dient und erweiterte Einstellungen und auch Steuerelement erlaubt. Größe, Farbe, Symbole nichts ist vorgegeben. Der Dialog hat nicht die Windows Backgroundfarbe und ich habe auch keine Möglichkeit gefunden diese auszulesen. Immerhin habe ich die Headline Schriftart auf Segeo UI und 25 Punkte Größe festgelegt. Die Breite des Standard Dialogs ist ca 360 Pixel. Man sollte volle Höhe nehmen, muss es aber nicht. Zum ein und ausblenden schiebt man diesen am besten per Code und Animation aus dem sichtbaren Bereich nach rechts.  Dies entspricht auch dem Windows 8 Standard Verhalten. Mein eigener Settings Dialog XAML <Grid Background="#FF878787" Margin="0"> <Grid.RowDefinitions> <RowDefinition Height="81"/> <RowDefinition /> </Grid.RowDefinitions> <TextBlock HorizontalAlignment="Left" Margin="73,32,0,0" TextWrapping="Wrap" Text="Einstellungen" VerticalAlignment="Top" FontSize="25" Width="189" Grid.Row="0" Height="24"/> <Button Style="{StaticResource SettingsBackButtonStyle}" Grid.Row="0" Click="Button_Click_1" Height="49" Width="49" Margin="20,20,0,10" /> <ToggleSwitch Header="ToggleSwitch" HorizontalAlignment="Left" Margin="20,10,0,0" Grid.Row="1" VerticalAlignment="Top" Height="73" Width="154" d:LayoutOverrides="VerticalMargin" /> </Grid> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Das sieht dann im Visual Studio Designer so aus. Nun stellt sich die Frage wie,binde ich den in den Code und Design ein. Die Antwort ist schwieriger als gedacht, In HTML gibt es ein Flyout Control, das dafür[r verwendet wird, da fehlt in XAML. Wenn ein Benutzer auf den Bereich des Screens clickt, der nicht in Settings liegt, muss dieses verschwinden, am besten auch noch animiert. Das muss man alles mit dem XAML Popup nachbilden und das Settings Usercontrol darin einbetten, Der XAML Code der eigentlichen METRO Anwendung. Das Attribut isLightDismissedEnabled bewirkt, das das popUp geschlossen wird,wenn daneben getoucht oder geklickt wird. <Popup Margin="0,0,-300,0" x:Name="setting1" Width="300" IsOpen="True" IsLightDismissEnabled="True" HorizontalAlignment="Right" > <local:Settings29 Margin="0" > <local:Settings29.Transitions> <TransitionCollection> <RepositionThemeTransition/> </TransitionCollection> </local:Settings29.Transitions> </local:Settings29> </Popup> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }   Das Event Settings geöffnet abfangen Private Sub UserControl29_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded AddHandler SettingsPane.GetForCurrentView().CommandsRequested, AddressOf OnSettings End Sub .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Und dann das neue Command in die Settings Kommand Liste einfügen Protected Sub OnSettings(sender As SettingsPane, args As SettingsPaneCommandsRequestedEventArgs) Dim h As New SettingsCommand("custome1ID", "Custom29", New UICommandInvokedHandler(AddressOf CFunktion)) args.Request.ApplicationCommands.Add(h) End Sub .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Beim Click auf das Setting, schiebt sich dann von rechts außen das popup, samt Settings Dialog in den Sichtbaren Bereich. Um sicherzustellen,das das Popup auch auf isopen= true ist, setzen. Private Sub CFunktion() setting1.IsOpen = True setting1.Margin = ThicknessHelper.FromLengths(0, 0, 0, 0) End Sub .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }   Den BackButton habe ich mir aus anderem SDK Beispiel Projekten mit der Datei Customstyles.xaml geklaut. Ganz glücklich bin ich nicht, aber die anderen BackButton Styles sind grösser. Mit Visual Studio 11 lassen sich diese auch im Eigenschaftsfenster zuweisen.

APP und Windows 8 Design Richtlinien

Oberflächen Gestaltung ist auch eine Frage der Rahmenbedingungen. In Windows 8 ist dieser Rahmen schon ein recht enges Korsett.  Mann kann die Entwurfsrichtlinien zwar in die Ecke Werfen, sollte man aber nicht Ich habe kurz zusammengeschrieben. Alles was  aus User Interface Sicht zu beachten ist, ohne Esoterisches ala “craftmanship” zu zitieren. Chromeless Windows 8 METRO Styled APPs haben nichts, keinen Rahmen, keinen Close Button- nichts. Optisch wie eine Internet Explorer Kioskanwendung. Das muss man nicht beachten, das ist einfach so. Interessant wird es wenn man Menüs einblenden möchte, dafür sind die Appbars gedacht. Dies wiederum, soll man nur innerhalb einer “Page” einsetzen. Es gibt eine oben und eine unten. Die Bottom Appbar soll für Kommandos eingesetzt werden, wie”neu”. Die Top Appbar ist mehr ein Navigationselement wie im Internet Explorer. Layoutrichtline besagt, die Buttons auf der Appbar sollen im Bereich des Daumens liegen, also links- Rechts Bildschirmrand.   Kontext Menü Ist eine schwierige Sache. Ist zwar grundsätzlich möglich, nützt aber nichts wenn der Dicke Daumen drüber ist. Bei der Appbar ist es möglich mit dem JavaScript Flyout Control oder mit dem ähnlichen XAML popup, ein Submenue nachzubilden. Suche Wenn die eigene Anwendung die Suche nach einem Begriff unterstützen soll, z.B. eine CD Verwaltung, dann soll das per Contract  und Charme gelöst werden. Die Suchergebnisse können in dem Charme eingeblendet werden, oder auch in der Anwendung. die Technischen Details werden hier nicht behandelt,sondern rein Layout Aspekte. Ganz wichtig ist, wenn die APP Suche als Hauptzweck hat, z.B. Immobilien und damit auch komplexere Suchdialoge benötigt, dann wird dies in der Anwendung direkt gehandhabt. Splash  Screen Eine seltsame Möglichkeit dem Benutzer die ersten paar Sekunden zu vertreiben. Settings Die Einstellungen einer APP sollten immer über den Setting Charme erfolgen. Leider kann man dort nicht direkt Steuerelement per Drag&Drop platzieren, sondern muss dies per Code tun. Ich mutmaße, das dies ein erbe von HTML5 ist,da dort im DOM auch immer neue Knoten eingebaut werden. Das XAML typische laden eines Usercontrols in eine Child Collection geht nicht direkt. Der Detaildialog kann dann natürlich per deklarativen XAML erstellt werden. Die Frage die sich oft stellt,ist dies ein Setting oder ein Kommando. Scrollen Für Daten verwendet man häufig das Gridview. Der Benutzer scrollt dann von Links nach rechts. In Kombination mit Gruppierung bietet sich dann das SemanticZoomControl an. Auch für die Navigation im Sinner von verschiedenen Programmfunktionen kann das selbe des zoomings Konzept verwendet werden.   ViewStatus Reichlich ungewohnt ist, das man vier Bildschirme designen muss Fullscreen ganzer Bildschirm Snapped seitliche Hochkant Ansicht Fill (zwei Apps nebeneinander) Portrait Bildschirm 90Grad gedreht Geteilte Funktion Das gesamte Contract  Konzept erlaubt über Share Source und Share Target Funktionen zu teilen. So muss man keine Kamera Funktion in die eigene Anwendung einbauen, sondern man kann den Benutzer die Bildquelle auswählen lassen. Typische Share Anwendungsfälle sind z.B. Adresse verwalten oder Mail versenden. Tiles Die Kacheln als Menuicon zu sehen, ist reichlich untertrieben. Kacheln sind kleine Anwendungen mit Bildern, Texten und Animationen. Desiged werden diese mit einer eigene XML Sprache, leider auch nicht mit XAML (winke winke Richtung Javascript) Finger Touch braucht Finger und zwar 1 bis n Finger. Finger können auch etwas dicker sein.   Die offizielle MSDN Doku Fact Sheet zu Touch Bedienung von Microsoft

REST Service mit Login

Eine noch immer häufige Benutzer Authentifizierung ist Basic Clear Text. Dabei wird Benutzername und Passwort einfach Base64 endcodiert übergeben. In meinem Windows 8 Beispiel rufe ich einfach eine Datei auf einem IIS an, die nur ein bestimmter Benutzer anfordern darf. Das könnte natürlich auch ein REST basierter Service sein. Im ersten Versuch wird man vermutlich eine 401 Fehlermeldung erhalten, wenn man nur den HTTPClient verwendet. In den Metro Design Style Guide steht geschrieben, das Fehlermeldungen direkt im Userinterface (also ohne popup) angezeigt werden soll. In den Request kann man sich per HTTPClientHandler einhaken. So ist auch der Zugriff auf Cookies möglich. In diesem Fall übergeben wir passende Credentials für die Authentifizierung am Webserver. Dim url As New Uri("http://win8-pre9/lab1/security/geheim.txt") Dim h As HttpClientHandler = New HttpClientHandler() Dim c = New Net.NetworkCredential("test", "admin") h.Credentials = c Dim http As New HttpClient(h) Try Dim txt = Await http.GetStringAsync(url) textbox1.Text = txt Catch ex As Exception error1.Text = ex.Message error1.Visibility = Visibility.Visible End Try .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Dies ist VB.NET Code für WinRT.

WinRT und .NET native oder IL?

Immer wieder kommt es zu Diskussionen was denn nun? Ist eine Windows 8 METRO APP native oder .NET? Die berühmte Marketing Grafik von Microsoft zu dem Thema finde ich persönlich wenig erhellend. Es gibt aber auch eine bessere. Die Runtime bietet eine Reihe von Funktionen per API an, wie z.B. Datei lesen und schreiben. Wer Komponenten für die WinRT schreiben möchte, kann dies per C++ tun. Das Modell ist an COM angelehnt. Auf der Runtime kann stand heute in mindestens drei verschiedenen Frameworks programmiert werden. Dabei handelt es sich bei der CRT (Common Runtime) um echtes .NET mit all seinen Eigenschaften wie automatische Garbage Collection, Intermediate Language und den Sprachen VB.NET und C#. Microsoft spricht von einem limitierten .NET Profil, da der Funktionsumfang erheblich geringer ist. Es ist auch nicht möglich .NET Assemblies außerhalb des Profils zu referenzieren. Die Beschreibung derselben erfolgt in einem neuen Format WinMD (Windows Metadata). Für den Entwickler ist es oft nicht ganz leicht zu erkennen ob er gerade einen WinRT API Call durchführt oder eine .NET Funktion aufruft. Wichtigster Hinweis sind die Namensräume die mit System für .net und Windows für WinRT beginnen. Dies ist von erheblicher Bedeutung, da die Datentypen zwischen WinRT und .NET unterschiedlich sind und vom System per Projektion automatisch gemappt werden müssen. In der folgende Tabelle werden einige davon genannt und man sieht das die WinRT Typen gerne mit I beginnen. Windows Runtime .NET Framework IIterable<T> IEnumerable<T> IIterator<T> IEnumerator<T> IVector<T> IList<T> IVectorView<T> IReadOnlyList<T> IMap<K, V> IDictionary<TKey, TValue> IMapView<K, V> IReadOnlyDictionary<TKey, TValue> IBindableIterable IEnumerable IBindableVector IList IObserableVector ObservableCollection Offene Frage ist, welche Performance Auswirkungen der zusätzliche .NET Framework Layer hat. Nicht verifizierte Aussagen behaupten, das HTML/JavaScript Anwendungen schneller sein könnten. Grundsätzlich ist ziemlich wahrscheinlich, das es unterschiede gibt. Wenig wahrscheinlich ist, das diese eine Rolle spielen.

Windows 8 Icons

In der Appbar von Windows 8 METRO Styled APPS werden die Buttons platziert um den Benutzer Aktionen  ausführen zu lassen. Die einfachste Möglichkeit ist es, dort Buttons zu platzieren und per Text Attribut zu beschriften, Möglich macht dies die Schriftart Segoe UI Symbol. Fehlt nur noch welcher Code welches Icon erzeugt Um alle Symbole auszugeben habe ich mir eine VB.NET Testanwendung geschrieben. Private Sub UserControl28_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded Dim startIndex = &HE10F - 300 Dim endIndex = startIndex + 1000 Dim l As New List(Of car) For i As Integer = startIndex To endIndex - 1 l.Add(New car With {.Zeichen = ChrW(i), .Code = String.Format("0x{0:X}:", i)}) Next gridview1.ItemsSource = l End Sub End Class Public Class car Property Zeichen As String Property Code As String End Class Im XAML wird dann das Zeichen einfach per Binding gebunden und der Charakter Code ausgegeben, .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } <GridView x:Name="gridview1" HorizontalAlignment="Left" Margin="0" VerticalAlignment="Top" > <GridView.ItemTemplate> <DataTemplate> <Border CornerRadius="5" BorderThickness="2" BorderBrush="White"> <StackPanel> <TextBlock Text="{Binding Zeichen}" FontFamily="Segoe UI Symbol" FontSize="20"/> <TextBlock Text="{Binding Code}"/> </StackPanel> </Border> </DataTemplate> ... .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Das Ergebnis als laufende Anwendung

Windows 8 Touch 1x1

Auch wenn man das Gefühl hat Touch ist das zentrale Konzept von Windows 8, so lässt sich doch jede Anwendung mindestens genauso gut mit der Maus und Tastatur bedienen. Der Entwickler muss dies auch kaum berücksichtigen, da die vorhandenen Steuerelemente diese automatisch handhaben. Ein wenig überraschend reduziert sich die Anzahl der Gesten auf einige wenige. Im Folgenden werden Gesten und deren Anwendung beschrieben Tab führt Aktion aus ähnlich dem Maus Click, also zum Start einer Anwendung oder Auswahl eines Listenelements. Es existiert auch ein Double Tabbed. Tab Hold. Üblicherweise werden z.B. Aktivitäten mit der Zwischenablage so ausgelöst. Zoom. Damit vergrößert man z.B. ein Bild. Wird auch genutzt mit dem Semantic Zoom Control um gruppierte Sichten einer Datenmenge zu darzustellen. Das Startmenü nutzt das um eine Navigation über die Anfangsbuchstaben zu ermöglichen Drehen eines Objektes. Slide Rechts Links, Damit kann der sichtbare Fensterausschnitt verändert werden, wie beim Startmenü. Slide über den linken Bildschirmrand wechselt die sichtbare METRO APP. Slide auf der rechten Seite über den Bildschirmrand von außen zeigt das Charme Menü. Slide Up and Down. Eine Anwendung wird geschlossen indem man über den oberen Bildschirm Rand diese ganz nach unten zieht. Wenn man nur wenige Zentimeter zieht, werden die Appbars Menü Controls eingeblendet. In Grid Darstellung wird der Slide auf dem Objekt nach unten genutzt um das Objekt auszuwählen, Beispiel Startmenü. Typischerweise werden die Slide Gesten mit dem Daumen ausgeführt. Mögliche Aktionen Appbar anzeigen, Appbar Aktion ausführen, Charme einblenden Windows 8 bietet für die Gestik Erkennung eigene Events an. Der Entwickler kann auch eigene komplexe Gesture Events erstellen, z.B. ein Up Down mit zwei Fingern. Standard Gesten sind Tapped, DoubleTapped, RightTapped, und Holding. Häufiger wird man mit den Pointer Events arbeiten die universell für Maus, Stift und Touch gefeuert werden. Aus .Net Bekanntes wie MouseleftButtonDown existiert in WinRT nicht mehr. Ersatz ist dann z.B. PointerPressed. Für Aktionen die mehrere Finger benötigen wird das Event Manipulation verwendet.

Windows 8 Push Notification Services WNS

In frühen Windows Versionen war einen Nachricht vom Betriebssystem ein übliches Szenario für den Entwickler. Gängige Anwendungen stellen dazu eine dauerhafte Verbindung (Connection) zu z.B. einer Datenbank her. Solche statefull Szenarien brachten schnell die Server Dienste an die physikalischen Leistungsgrenzen, so das auf einen asynchronen Ansatz gewechselt wurde. Webserver sind ein klassischer Ansatz dafür. Aber plötzlich fehlt die Möglichkeit dem Client etwas mitzuteilen ohne das dieser einen kontinuierlichen Pull oder Request ausführen muss. Im Web Umfeld gibt es nun die neuen Websockets, die man auch in Windows 8 METRO Anwendungen u.a. für Push  verwenden kann. Windows 8 hat aber andere Anforderungen., die mit Windows Push Notification Services gelöst werden können Push in eine laufende METRO Anwendung Push auf eine inaktive METRO Anwendung auf die Tiles, Badges, und MessageDialog PopUp Push auf Lockscreen um z.B neue Mails anzuzeigen Die Dokumentation zum Thema ist durchaus umfangreich für mich aber verwirrend. Ein Fundstück behandelt die Erstellung eines Azure Beispiels in nur 4 Minuten und Techno Musik hinterlegt. Das dort angesprochene Windows Azure Toolkit for Windows 8 , lässt sich weder installieren noch ist es überhaupt nötig. Für einen minimalistischen Prototyp braucht man drei Dinge Registrierung bei Push Service METRO Anwendung die den Push Kanal abonniert Testanwendung um Push Nachrichten u versenden.(zb WPF)   Um das ganze einfach zu gestalten, lasse ich Punkt drei weg, Sie lernen nur das Konzept und nicht die Anwendung kennen. Es gibt wohl mehrerer Möglichkeiten um einen Push Service anzulegen, ohne Windows 8 Developer Account ( und den aktuell   quasi keiner hat) muss man einen Live Service nutzen. Ist kostenfrei und kann 100 Kanäle veralten. Ich gehe mal davon aus das den Wizard jeder bedienen kann. Nachdem man seine Anwendung erzeugt hat. muss im Manifest der METRO APP die Infos aus der Website eingegeben werden, Die (Punkt 3) Client Anwendung für das Senden der Push Nachrichten, benötigt für die oAuth Authentifizierung das SECRET und die SID aus dem Web Dialog. Die Windows 8 METRO styled APP kann dann mit einer Zeile Code  aus dem WinRT Networking Namensraum  den Kanal öffnen. Dim op = Await Windows.Networking.PushNotifications.PushNotificationChannelManager. CreatePushNotificationChannelForApplicationAsync() .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }   Ganz wichtig ist der Kanalname, den man den man als Rückgabe (hier op.Uri) erhält.  Diesen braucht die Push Anwendung als dritten Parameter um auch mit dem richtigen Push Service zu kommunizieren. Damit kann das Windows 8 System für Badge, Tile, Toast und Raw Nachrichten entgegen nehmen. Hier ein Screenshot für Badge. Es wurde der String 99 gesendet, der dann rechts unten im Eck erscheint. Wenn auch die METRO APP das Event mitbekommen soll muss es registriert werden. Private Async Function Button_Click_1(sender As Object, e As RoutedEventArgs) As Task Dim op = Await Windows.Networking.PushNotifications.PushNotificationChannelManager. CreatePushNotificationChannelForApplicationAsync() AddHandler op.PushNotificationReceived, AddressOf gepushed Layoutroot1.DataContext = op End Function .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Die Rücksprung Prozedur läuft natürlich im Background Thread und muss der Dispatcher erst synchronisiert werde um in der UI einen MessageDialog starten zu können. Private Async Sub gepushed(sender As Windows.Networking.PushNotifications.PushNotificationChannel, args As Windows.Networking.PushNotifications.PushNotificationReceivedEventArgs) Select Case args.NotificationType Case Windows.Networking.PushNotifications.PushNotificationType.Badge Dispatcher.InvokeAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, Async Sub(s As Object, e As InvokedHandlerArgs) Dim msg As MessageDialog = New MessageDialog(args.BadgeNotification.Content.GetXml) Await msg.ShowAsync() End Sub, sender, args) End Select End Sub .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }   Die Methode hat etwas Overhead. Der Case Selector filtert mit Badge schon eines der möglichen vier Notification Events heraus. Nochmal zur Verdeutlichung Der Pusher (Punkt 3) kann mit jedwelcher Technologie geschrieben werden, Also z.B, ASP.NET, WPF, WInforms, Silverlight und co. Es gibt jeweils XML Formate mit denen die Push Nachrichten erstellt und per HTTP POST an den WNS gesendet werden müssen. Einsatzzweck sind im begrenzten Umfang Benachrichtigungen wie neue SMS oder eMail. Windows 8 kennt einen Connected Stand-by Modus im de auch die WNS Nachrichten, mit technologobedingter Verzögerung zugestellt werden.