Liste 2x1 Itemscontrol

Letztes mal habe ich kurz beschrieben was man mit einer Listbox und Templating in Silverlight so machen kann. Wenn man allerdings keine Auswahl Möglichkeit braucht, kann man auch das schlankere Itemscontrol (übrigens erbt Listbox davon) verwendet werden. Die Daten werden als Liste in einer Klasse erzeugt. Public Class personen Inherits List(Of person) Public Sub New() Add(New person With {.alter = 27, .Firma = "ppedv ag", .Name = "Hannes"}) Add(New person With {.alter = 32, .Firma = "ppedv ag", .Name = "Andreas"}) Add(New person With {.alter = 23, .Firma = "ppedv ag", .Name = "Bernhard"}) Add(New person With {.alter = 45, .Firma = "ppedv ag", .Name = "Stefan"}) Add(New person With {.alter = 12, .Firma = "ppedv ag", .Name = "Arnold"}) End Sub End Class Diese Daten werden deklarativ instanziert und gebunden. Nicht weil es nötig wäre, sondern schlicht weil es möglich ist. Das folgende passiert dann auch in der XAML Datei ... xmlns:local="clr-namespace:KoelnSL"> <UserControl.Resources> <local:personen x:Key="personen"></local:personen> </UserControl.Resources> Ein positver Nebeneffekt ist, das die Bindung auch in Blend und Visual Studio 2010 zur Entwurfszeit voll sichtbar ist. Im XAML werden dann die drei Templates definiert   <ItemsControl Width="100" ItemsSource="{Binding Source={StaticResource personen}}"> <ItemsControl.Template> <ControlTemplate TargetType="ItemsControl"> <Border BorderBrush="BlueViolet" BorderThickness="1" CornerRadius="10"> <ItemsPresenter/> </Border> </ControlTemplate> </ItemsControl.Template> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <StackPanel Orientation="Vertical" Background="SkyBlue" Margin="5"/> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding Name}" Height="20" Width="50" Margin="4"></TextBlock> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl>

Freigestellte Personen in Silverlight Video

Auf jedem guten TV Sender gibt es eine Wetter Fee. Diese meist sehr attraktive Person  choreographiert vor einer blauen oder heute meist grünen Wand. Die Clouds oder Sonnen werden Computer animiert eingespielt. Dazu brauchen wir eine Wetterfee, eine Kamera, ein Aufnahmestudio, Expression Blend 4 und .. die Möglichkeit in einem  Video eine Farbe auf transparent zu schalten. Die Wetterfee ist meine entzückende Kollegin Lilly. Die Kamera eine Smartflip ( jetzt Cisco). Das Aufnahmestudio eines Fotografen der im gleichen Haus sitzt und eine grüne Rollwand besitzt. Diese rollt man ein Stück über den Boden so das auch keine Kanten sichtbar sind. Dann das ganze nach Expression Blend importiert und per Drag& Drop auf eine Seite ziehen. Warum Lilly hier so seltsame Handbewegungen macht? Ich wollte später eine per Silverlight Animation eine Sonne durchs Bild schieben. Was man hier gut sehen kann ist, das der Hintergrund nicht homogen ist. Das ist mir bei unserem 30 Sekunden Shot nicht aufgefallen. Es liegt daran das Fotografen in der Regel einen Spot auf den Hintergrund legen um das Foto aufzulockern. Hier müsste der Spot abgeschalten werden. Dazu aber gleich mehr. Seit Silverlight 3 gibt es Pixelshader. Diese helfen Bilder direkt in der Grafikkarte performant zu verändern( Wenn GPU Acceleration aktiviert ist). Per Standard ist Schatten und Unschärfe vorhanden. In Blend 4 noch ein wenig mehr Shader. Wir brauchen aber einen Pixelshader der aus Grün Transparent macht. Dies nennt man fachspezfisch den ChromaKey fürs Alpha Blending. Entsprechend auch der Name ChromaKeyAlphaEffect. Der Download für die installierbare MSI findet sich hier http://code.msdn.microsoft.com/SL3ChromaKeyEffect/Release/ProjectReleases.aspx?ReleaseId=3900 Leider ist der aktuelle Build 1.3 vom 9.Februar.2010 noch SL 3. Entsprechend ist Blend 4 und Visual Studio 2010 ein wenig mit der Aufgabe überfordert und man benötigt etwas Handarbeit. Zunächst setzt man eine Referenz im Silverlight Projekt auf Synergist.Effects.dll. Dann kann man in Expression Blend im Reiter Assets den Chroma Key Alpha Effect auf das Video ziehen. Im Property Dialog sollte dann entweder direkt in den Eigenschaften des ChromaAlphaEffect (siehe Bild) oder in den Eigenschaften des Videos im Effect Reiter die Farbe ausgewählt werden können. Am besten geht das mit dem Color Picker des üblichen Farbdialoges. Leider tritt hier der erste Bug zu Tage. Das zusätzliche Property Tolerance wird nicht angeboten. Damit kann man den Grünbereich etwas aufweiten. Mögliche Werte sind 0-1. Ganz gut trifft oft rund um 0,2. Aktuell sieht dann Lilly so aus. Wenn man im XAML Source dann Tolerance setzt, <MediaElement x:Name="lilly1_wmv" Source="lilly1.wmv" Stretch="Fill" AutoPlay="True" MediaEnded="lilly1_wmv_MediaEnded" > <MediaElement.Effect> <Synergist_Effects:ChromaKeyAlphaEffect Tolerance="0.2" ColorKey="#FF9DE094"/> </MediaElement.Effect> </MediaElement siehts in Blend so aus. In Visual Studio 2010 ist es im Ergebnis das gleiche. Allerdings lauffähig ist das ganze schon. Also ab  in den Browser und staunen. Noch nicht perfekt und ich habe deswegen auf die Animation verzichtet aber ich glaube wir machen noch einen zweiten Dreh mit besseren Hintergrund.

Silverlight WCF Services 1x1

In den nächsten Blog Einträgen werde ich meine Gedanken zum Thema Services mit Silverlight zu ordnen beginnen. Es gibt einfach zu viele Wege um Daten mit der Client Server Technologie Silverlight hin und her zu schicken. Leider sind die recht einfachen ASMX Web Services obsolet und in  WCF aufgegangen. Der größte Unterschied ist das man WCF (Windows Communication Foundation) Dienste nicht mal so spaßeshalber im Browser aufrufen kann. Ergänzend der Hinweis auf das Blog meines Kollegen Bernhard, der ein wahres WCF Genie ist. Zunächst einmal die Vorarbeit mit einer Datenklasse. Imports System.Runtime.Serialization <DataContract()> Public Class person Private _FamName As String <DataMember()> Public Property FamName() As String Get Return _FamName End Get Set(ByVal value As String) _FamName = value End Set End Property Private _GebDat As Date <DataMember()> Public Property GebDat() As Date Get Return _GebDat End Get Set(ByVal value As Date) _GebDat = value End Set End Property Private _bild As String <DataMember()> Public Property bild() As String Get Return _bild End Get Set(ByVal value As String) _bild = value End Set End Property End Class Wenn DataMember nicht dekoriert wird, gibt es später beim aufrufen des Services einen deserialisierungsfehler in der Form InnerException: System.Runtime.Serialization.SerializationException. Das sind eben WCF Basics. Dann erstelle ich eine Business Objekt das mir eine Liste von Personen zurück gibt. Public Class BO1 Public Function getPersonen() As List(Of person) Dim lofP As New List(Of person) lofP.Add(New person With {.bild = "bild1.jpg", .FamName = "Maier", .GebDat = New Date(("01.13.1978"))}) lofP.Add(New person With {.bild = "bild2.jpg", .FamName = "Huber", .GebDat = New Date("01.13.1978")}) lofP.Add(New person With {.bild = "bild3.jpg", .FamName = "Müller", .GebDat = New Date("01.13.1978")}) lofP.Add(New person With {.bild = "bild4.jpg", .FamName = "Gates", .GebDat = New Date("01.13.1978")}) lofP.Add(New person With {.bild = "bild5.jpg", .FamName = "Heuer", .GebDat = New Date("01.13.1978")}) lofP.Add(New person With {.bild = "bild6.jpg", .FamName = "Holesch", .GebDat = New Date("01.13.1978")}) lofP.Add(New person With {.bild = "bild7.jpg", .FamName = "dela Rosa", .GebDat = New Date("01.13.1978")}) lofP.Add(New person With {.bild = "bild8.jpg", .FamName = "Jobs", .GebDat = New Date("01.13.1978")}) lofP.Add(New person With {.bild = "bild9.jpg", .FamName = "Hayat", .GebDat = New Date("01.13.1978")}) lofP.Add(New person With {.bild = "bild10.jpg", .FamName = "Hatahet", .GebDat = New Date("01.13.1978")}) lofP.Add(New person With {.bild = "bild11.jpg", .FamName = "Thyret", .GebDat = New Date("01.13.1978")}) Return lofP End Function End Class Ein WCF Service wird im Silverlight Projekt per Template Silverlight-Enabled-WCF-Service erstellt. Dieser Service ruft dann die Funktion auf, die die Personenliste erstellt. Per Dafult findet sich da immer die DoWork Prozedur. <OperationContract()> Public Function GetAllPersons() As List(Of person) Dim bo As New BO1 Return bo.getPersonen() End Function Der Service ist im Browser aufrufbar. Mit dem Parameter WSDL erscheint auch die Beschreibung der Funktion und Objekte. Diese wird von Werkzeugen verwendet um Proxy Klassen erzeugen zu können. Das sollten Sie für einen ersten Test auf alle Fälle tun.   Dann wechseln wir in das Silverlight Projekt und erstellen eine Service Referenz im Projekt Baum per Context Menü Add Service. In der Silverlight Anwendung wird dann eine Instanz der Proxy Klasse erzeugt, eine Rücksprung Methode definiert und der Service aufgerufen. Vergessen Sie nicht, das Silverlight nur Asynchron arbeitet und deswegen nicht auf eine Rückgabe wartet.  Die eigentliche Liste von Personen wird dann per e.Result in der Rücksprung Methode ausgelesen und einem Datagrid zugewiesen. Hier passiert eine wenig VB casting magic. Sie sollten wissen das  der Visual Studio Proxy Wizard immer aus Listen einen Typ ObservableCollection erzeugt. ich habe bereits hierzu ein paar Worte verloren, das das auch anders geht. Private Sub WCF1_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded Dim svc As New ServiceReference1.Service1Client AddHandler svc.GetAllPersonsCompleted, AddressOf fertig svc.GetAllPersonsAsync() End Sub Private Sub fertig(ByVal sender As Object, ByVal e As ServiceReference1.GetAllPersonsCompletedEventArgs) SVC1.ServiceReference1.person) DataGrid1.ItemsSource = e.Result End Sub

RIA Services binary, Json, Odata und SOAP Endpunkte

Mit Hilfe des Silverlight RIA Services Toolkit lassen sich zusätzliche Optionen der RIA Services nutzen. LinqToSql DomainService SOAP Endpoint JSON Endpoint  ASP.NET DomainDataSource Control In diesem Blog Eintrag betrachte ich einmal die Möglichkeiten der serialisierung. Insgesamt kann man stand heute folgenden Formate wählen. Binary OData SOAP JSON Allerdings muss in der Web.Config manuell die Konfiguration erweitert werden. <domainServices> <endpoints> <add name="OData" type="System.ServiceModel.DomainServices.Hosting.ODataEndpointFactory, System.ServiceModel.DomainServices.Hosting.OData, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> <add name="JSON" type="Microsoft.ServiceModel.DomainServices.Hosting.JsonEndpointFactory, Microsoft.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> <add name="Soap" type="Microsoft.ServiceModel.DomainServices.Hosting.SoapXmlEndpointFactory, Microsoft.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> </endpoints> </domainServices> Der Aufruf für eine JSon Rückgabe erfolgt in der Form http://localhost:[port]/ClientBin/[Projektname]-Web-[DomainServiceklasse].svc/Json/[Methode] Da die SVC Dateien nicht wirklich existieren sondern per IIS Modul Mapping behandelt werden kann der Pfad statt Clientbin auch z.B. Service lauten. Wenn man den Traffic mit Fiddler mitschneidet kann man sehr gut erkennen wie das Json Format aufgebaut ist. Die Aufrufe der einzelnen Methoden und die Rückgabe Datenmenge in KB im Vergleich ..KoelnSL-Web-DomainServiceMD.svc/binary/GetOrdersDetails 607K ..KoelnSL-Web-DomainServiceMD.svc/Json/GetOrdersDetails 563K ..KoelnSL-Web-DomainServiceMD.svc/OData/GetOrdersDetails 1109K ..KoelnSL-Web-DomainServiceMD.svc/Soap/GetOrdersDetails erzeugt 400er Error Soap Abrufe sind leider im Browser nicht direkt möglich. Deshalb auch die Fehlermeldung. Um den Service bzw die Methode testweise aufzurufen könnten man das Hilfstool WCFtestClient.exe verwenden. Leider unterstützt dieses keine Domainservices. Also bleibt nur der Weg über das Silverlight Projekt. Leider kompiliert meine Lösung anschliessend nicht mehr. Selbst auf Nachfrage bei Microsoft konnte man adhoc das Problem nicht lösen. Die einzige Antwort das es aktuellere Bits der RIA Services und Silverlight (GDR) gibt hilft nicht, da ich dafür alles neu installieren muss und dann mit RC Bits arbeite die nirgendwo laufen. Entsprechend werde ich die Lösung für SOAP in einem späteren Blog nachliefern.

Master Detail mit WCF RIA Services in 10 Sekunden

Die Headline stimmt nur bedingt, aber schliesslich muss ich meinen Artikel ja verkaufen . Am Ende ist es aber auch nicht ganz falsch. Wenn ein Silverlight Projekt mit RIA Services besteht, ist Master Detail tatsächlich nur 1 Codezeile und 2 clicks entfernt. Zunächst einmal nehme ich die gute alte Nordwind Datenbank und die Tabellen Orders und OrderDetails als Ausgangspunkt und erstelle im Web Projekt mit Entity Framework ein Modell. Weiter geht es mit einer neuen Domain Service Klasse. Wie immer vorher kompilieren nicht vergessen und die Metadaten erzeugen lassen. In der DomainService Klasse erzeuge ich per copy paste eine weitere Queryklasse. Per Standard findet sich nur die GetOrders. Da ich ja noch die Details mit liefern möchte nenne ich die Funktion GetOrdersDetails. Wichtig ist per LINQ Query und dem Kommando Include die Kind Tabelle Order_Details einzubinden. Mit dem Attribut <Query> stelle ich sicher das später im Data Designer die Query auch auftaucht. <Query()> _ Public Function GetOrdersDetails() As IQueryable(Of Orders) Return Me.ObjectContext.Orders.Include("Order_Details") End Function Dann muss in den Metadaten (xxx.metadata.vb) noch der Schlüssel Property markiert werden. Dazu wird <Include()> vor den bereits vorhandenen Propertynamen vorgestellt. <Include()> Public Property Order_Details As EntityCollection(Of Order_Details) Seit VB 2010 braucht man dafür übrigens keinen Unterstrich mehr *like`*. Dann wieder kompilieren. In Visual Studio ins Silverligth Projekt wechseln und eine XAML Datei auswählen. Dann ist der Menüpunkt Data vorhanden. Dort einfach die Darstellungsform Datagrid einstellen und die Orders und die Order Details auf die Page ziehen.   Das fertige Ergebnis nach 9,67 Sekunden im Browser

klare Regeln frs tgliche Leben- Die sterreichische Ampel App mit Silverlight

Ich habe mir einen Wunschtraum erfüllt. Eine österreische Ampel als mini App. Da Windows Phone noch kein Silverlight unterstützt, vorerst nur als Desktop Anwendung Was macht nun eine österreichische Ampel so einmalig. Sie blinkt 3 mal Grün bevor sie auf gelb schaltet! Diese Ampel kann uns nun den Arbeitsalltag versüssen, gibt uns klare Richtlinien vor. Sinnlosses Starren auf den  Fortschrittsbalken ist nun endgültig vorbei. Jetzt kommt sinnloses Starren auf die Ampel. Ich bitte um Überweisung von 3,99 € pro Download. Reklamation und Rückgabe ausgeschlossen. Zunächst einmal das technsiche Konzept. Ich implementiere die Ampel als Usercontrol und nutze den Visual Statemanager um die Statusinformation Rot, Gelb und Grün mit Animationen hinterlegen zu können. Startpunkt ist das UI Design mit Blend. Es beginnt relativ harmlos mit einer Border, Farbverlauf und wie immer runden Ecken.   Dann widme ich mich der ersten Lampe. Ein Kreis mit etwas dickerem Rand (Strockethickness 10) und zwei gegenläufige Farbverläufe im Graubereich erzeugen einen 3D Eindruck. Da rein kommt dann nochmal ein kleinerer Kreis, der ein wenig Abstand zum äusseren Rahmen hat auf den ersten Kreis. So das man den Hintergrund am Rand noch ein wenig sehen kann. Dieser Kreis wird rot gefärbt und bekommt einen im Zentrum leicht versetzten runden Farbverlauf. Das GradientBrushtool ( dicker Pfeil) aus der linken Toolleiste hilft dabei ungemein. Um die die Wölbung perfekt zu machen, wird Lichteinfall von oben simuliert. Dazu wird ein weiße, sehr transparente Elypse, darüber gelegt. Das gleiche machen Comic Zeichner z.B. mit den großen Heidi Augen um diese wässrig aussehen zu lassen. Ich verwende hier 30% alpha blending und versüse das mit einem Effekt um ein unscharfe Kontur zu haben. Dann werden die Ui Element in ein Canvas gepackt, kopiert und umgefärbt. Weiter gehts mit dem Visual State Manager. Dort erzeuge ich eine Gruppe mit dem Namen Phasen und darin die drei States: rot, gelb und gruen. Dann kann jeder in jedem State und Übergang  das UI animiert werden. Im wesentlichen werden die beiden anderen Kreise einfach schwarz gefärbt mit einem Delay von 0,2 Sekunden. Schliesslich leuchtet so eine antike Glühbirne ja nach. LED Ampeln gibts in Österreich noch nicht. Für die Phase Grün auf Gelb habe ich einen speziellen Übergang definiert. Diese Animation läuft drei Sekunden und wechselt dabei von abwechselnd drei mal von Grün nach Schwarz den SolidcolorBrush im Fill Attribut. Als nächstes wird das Usercontrol in eine weitere XAML Seite eingepackt. Dort gehts dann nur mehr mit puren Code zur Sache. Ein Timer wirft die Statusänderungen an. Da die Ampelphasen ja unterschiedlich lang sind, brauch ich ein wenig Logik um die Timer Zeiten zu ändern.  Da die Grün Blink Phase 3 Sekunden dauert muss die Gelb Phase 5 Sekunden sein um in Summe 2 Sekunden Gelb zu sehen. Ich denke der Code spricht auch ohne refactoring für sich selbst Dim dp As New DispatcherTimer Dim status As Integer = 0 private Sub page35_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded dp.Interval = New TimeSpan(0, 0, 10) AddHandler dp.Tick, AddressOf ticking VisualStateManager.GoToState(Ampel1, "rot", True) status = 1 dp.Start() End Sub Private Sub ticking(ByVal sender As Object, ByVal e As EventArgs) Select Case status Case 0 VisualStateManager.GoToState(Ampel1, "rot", True) dp.Interval = New TimeSpan(0, 0, 10) status = 1 Case 1 VisualStateManager.GoToState(Ampel1, "gelb", True) dp.Interval = New TimeSpan(0, 0, 2) status = 2 Case 2 VisualStateManager.GoToState(Ampel1, "gruen", True) dp.Interval = New TimeSpan(0, 0, 10) status = 3 Case 3 VisualStateManager.GoToState(Ampel1, "gelb", True) dp.Interval = New TimeSpan(0, 0, 5) status = 0 End Select End Sub Jetzt habe ich nur mehr das Problem, wie komme ich an Ihr Geld. Bzw wie können Sie ganz einfach die Anwendung starten? Dazu rufen Sie einfach folgende Website auf. Per rechtsclick können Sie diese auch lokal installieren.

Silverlight kann nun auch rechts click

In meiner aktuellen Silverlight Schulung wurde heute das Thema Mouse Events besprochen. Seit Silverlight 4 gibt es ja bekannterweise auch Events zur rechten Maustaste.  Also sollte theoretisch auch eine Textbox per Rechstclick ein Context Menü anzeigen können. Die Idee des Schulungs Teilnehmers sah ungefähr so aus. <TextBox Height="111" MouseRightButtonUp="textBox1_MouseRightButtonUp" Name="textBox1" Width="180" /> Allerdings funktioniert das nicht, weil die Textbox das Event als behandelt markiert und damit nicht mehr weiter reicht. Um ein Context Menü zu erstellen gibt es aber seit Silverligth 4 im seperat erhältlichen Toolkit eine passende Lösung. Mit dem ContectMenuService wird ala Tooltip die Textbox um zusätzliche Funktion erweitert. Das Context Menü funktioniert genauso wie in WPF. Es besteht aus Menuitems. Pro Menüpunkt ein Item. Dieses wiederum aus einem Header, der üblicherweise den Menütext darstellt. Optisch aufgepeppt wird über ein Unterelement MenuItem.Icon per Image Element. Das Attribut Icon im MenuItem Element kann dafür nicht genutzt werden. Für den Trennstrich gibt es das Seperator Element. <TextBox Height="30" HorizontalAlignment="Left" Margin="161,36,0,0" Name="textBox1" VerticalAlignment="Top" Width="180" > <toolkit:ContextMenuService.ContextMenu> <toolkit:ContextMenu> <toolkit:MenuItem Header="Hyperlink" Click="MenuItem1_Click"> <toolkit:MenuItem.Icon> <Image Source="Images/link.png"></Image> </toolkit:MenuItem.Icon> </toolkit:MenuItem> <toolkit:Separator /> <toolkit:MenuItem Header="drucken" Click="MenuItem2_Click"> <toolkit:MenuItem.Icon> <Image Source="Images/print.png"></Image> </toolkit:MenuItem.Icon> </toolkit:MenuItem> <toolkit:MenuItem Header="speichern" Click="MenuItem3_Click" IsEnabled="True"> <toolkit:MenuItem.Icon> <Image Source="Images/save.png"></Image> </toolkit:MenuItem.Icon> </toolkit:MenuItem> </toolkit:ContextMenu> </toolkit:ContextMenuService.ContextMenu> </TextBox> In diesem Beispiel werden einzelne Events pro Menüpunkt deklariert. Denkbar ist auch per Commands zu arbeiten. Dann wird das Attribut Command bzw CommandParameter verwendet.

Silverlight Textbox mit Wasserzeichen

Eben sind die neuen Programme aus der Live Serie erschienen. Ich schreibe dies auch auf dem neuen Windows Live Writer Beta. Den gibts aktuell leider nur in Englisch und so muss ich auf die deutsche Rechtschreibprüfung verzichten. Man verzeihe mir schon jetzt. Was seit Beginn der Zune Zeiten auffällt, ist die Reduktion auf weniger. Also vor allem kurzer Text statt bunter Icons. Apple geht hier aktuell einen anderen Weg. Microsoft hat das ganze sogar in seinem Metro UI Style Guide beschrieben. Dort steht auch, das man Oberflächen bewusst leer halten soll. Eine alte Designer Regel.  Ausserdem soll man alle Elemente dem Benutzer zugänglich machen. Als Beispiel dafür  möchte ich die klassische Windows XResult Fehlermeldung nennen, deren Text man nicht in die Zwischenablage kopieren kann, da es als Label implementiert ist. Um das klar zu sagen, ich stehe zu beiden Aussagen. Das macht Sinn und ist die Zukunft. Ich habe mir nun einen einfachen Silverlight Login Dialog vorgenommen um dieses Design Pattern umzusetzen. Textblock ist eigentlich obsolet und gehört verboten. Entsprechend kommt die Beschriftung in die Textbox und verschwindet, wenn der Benutzer etwas eingetippt hat. Davon ausgehend, das der Benutzer auch nachträglich erkennen kann was der Inhalt bedeutet. Wenn die Textbox wieder geleert wird, erscheint die Watermark in wieder in Grau. Realisiert habe ich das ganz einfach. Zunächst wird der Watermark Text der Textbox im Tag und Text Element abgelegt und der Foreground Grau gesetzt. Das Ziel ist es die Watermark wieder herstellen zu können. Dann brauche ich nur mehr die Events GotFocus und LostFocus um minimale Funktion zu implementieren. <TextBox Height="26" Name="txtUser" Width="63" Margin="10" MaxLength="3" Foreground="gray" GotFocus="txt_GotFocus" LostFocus="txt_LostFocus" Text="User" Tag="User"> </TextBox> <TextBox Height="26" Name="txtPassword" Width="84" Foreground="gray" GotFocus="txt_GotFocus" LostFocus="txt_LostFocus" Text="Passwort" Tag="Password"></TextBox> Die Methoden sind universell ausgelegt und erkennen das Sender Control. Private Sub txt_LostFocus(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Dim tb As TextBox = CType(sender, TextBox) If (tb.Text = String.Empty) Then tb.Text = tb.Tag tb.Foreground = New SolidColorBrush(Colors.Gray) End If End Sub Private Sub txt_GotFocus(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Dim tb As TextBox = CType(sender, TextBox) If tb.Text = tb.Tag Then tb.Text = "" tb.Foreground = New SolidColorBrush(Colors.Black) End If End Sub Sieht doch schick aus, oder?

Silverlight Themes

Sind Sie ein Designer? Nein, aber möchten trotzdem schöne Oberflächen? Dann könnten die Silverlight Themes etwas für Sie sein. Es gibt aktuell drei Neue mit dem Namen Accent Color, Windows 7 und Cosmopolitan. Ursächlich sind diese für die sogenannte Silverlight Navigation oder Silverlight Business Application gedacht. Allerdings können die Styles auch anderwärtig verwendet werden. Dazu später mehr. Der Download für die Version 1.1 umfasst Style für die Silverlight Core, Silverlight SDK und Silverlight ToolkitControls. Es gibt drei einzelne Dateien •README_FIRST.txt – •SL4Themes-templates.zip –darin enthalten ein Ordner für Expression Blend und Visual Studio Templates.  Ebenso ist ein Unterordner für  RIA Services Templates. •SL4Themes-rawassets.zip – in dieser Datei stecken sozusagen die nackten Styles ohne Visual Studio Template. In der beigefügten Readme Datei ist beschrieben wie man ein SIlverlight Projekt mit manuell mit diesen Style versieht. Dies ist eigentlich recht einfach und für VB Entwickler der einzige Weg die Styles zu verwenden. SL4Themes-Templates Um die Themes für  Visual Studio 2010 zu installieren einfach die  *.vsix files im VS2010 Ordner starten. Um die Themes für Expression  Blend 4 muss man manuell die Dateien kopieren. Der Zielordner für Blend4 findet sich in  %ProgramFiles%\Microsoft Expression\Blend 4\ProjectTemplates\en\CSharp\Silverlight. Beim starten von Blend stehen dann die Templates zur Verfügung. In Visual Studio sieht das dann so aus Für beide Fälle gilt das dies nur in C# Projekten zur Verfügung steht. Mir klingt noch in den Ohren “VB.net is a first class citicen”. Für VB.NETler geht dann eben nur der Weg über SL4Themes-rawassets. Eine Silverlight Navigation Application mit dem Cosmopolitian Theme sieht ein wenig aus wie im Metro UI Style Guide definiert. Zune Anwendungen und zukünftige Windows phone Anwendungen folgen diesem recht nüchternen Text orientieren Design. Im Silverlight Projekt ist dies über den Assets Ordner zugeordnet. Dort finden sich in XAML Dateien die Styles. Die kann man natürlich nach eigenen Geschmack auch anpassen. Die Zuweisung der Styles findet in der app.xaml statt. <Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Assets/Styles.xaml"/> <ResourceDictionary Source="Assets/CoreStyles.xaml"/> <ResourceDictionary Source="Assets/SDKStyles.xaml"/> <!--<ResourceDictionary Source="Assets/ToolkitStyles.xaml"/> To extend this theme to include the toolkit controls: 1. Install the Silverlight Toolkit for Silverlight 4 2. Add a Toolkit control to your project from the toolbox. This will add references to toolkit assemblies. 3. Change the "Build Action" for ToolkitStyles.xaml to "Page" 4. Uncomment the resource dictionary include above. If you do not intend to use toolkit controls, delete this comment and the ToolkitStyles.xaml file.--> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources> Tim Heuer schreibt auch noch ein wenig in seinem Blog darüber. Komplette Beispielanwendungen als Design Muster http://www.silverlight.net/content/samples/sl4/themes/cosmopolitan.html http://www.silverlight.net/content/samples/sl4/themes/windows7.html http://www.silverlight.net/content/samples/sl4/themes/accent.html

Eingabe Validierung in WCF RIA Services

Wenn man beim erstellen eines Domainservices die Metadaten dazu erstellt, kann man sehr einfach per die Eigenschaften des Geschäftsobjekte deklarativ im Code mit Informationen versehen, die später zur Laufzeit ausgewertet werden. Also per <Attribut> Syntax.   Dadurch erhält man dann im Web Projekt Klassen in der Konvention DomainService1.metadata.vb. Im Code dieser Klasse kann dann per Annotation  die Logik jeder Eigenschaft gesteuert werden. Folgendes lässt in einem Dataform das Feld Telefon erscheinen und es wird Fett dargestellt, da es ein muss Feld ist. Darüber erscheint es ziemlich weit oben. <Required()> <Display(Name:="Telefon", Order:=2)> Public Property Phone As String Was passiert nun wen Benutzer keine Telefonnummer angibt und das Feld leer lässt?   Natürlich kann man auch den Fehlertext noch ändern. Dazu einfach im Required ErrorMessage:= setzen. Diese Prüfung der Benutzereingabe findet Adhoc, also nach verlassen des Eingabefeldes statt. Ohne Interaktion zum Server. Für komplexere Validierungen stellt Silverlight ein Benutzerdefinierte Prüfung sowohl am Client als auch am  Server bereit. Dazu wird das entsprechende Property in der IRA DomainKlasse per Attribut Customvalidatiion dekoriert. Der erste Parameter stellt den Klassennamen dar und der zweite die Methode. <CustomValidation(GetType(regeln), "hannesValid")> Der Prüfcode muss eine gewissen Regelwerk folgen, sonst wird er schlicht nicht ausgeführt. Zunächst muss die Prüfroutine shared (c# static) sein. Die Rückgabe muss vom Typ Validationresult sein. Imports System.ComponentModel.DataAnnotations Public Class regeln Public Shared Function hannesValid(ByVal region As String) As ValidationResult If region.Length > 2 Then Return New ValidationResult("nur 2 Zeichen") End If Return ValidationResult.Success End Function End Class Das wird nun eine reine Prüfung am Server bewirken. Also erst wenn der Datensatz nach einer Änderung zurück geschrieben wird. Mit Hilfe von Shared Code kann diese Prüfung aber auch am Client sofort durchgeführt werden. Zeitpunkt ist wenn die Datenbindung aktualisiert wird, also bei LostFocus. Die Prüfungsklasse muss nun in der Web Anwendung in einer eigenen Datei erstellt werden die der Namens Konvention shared.vb oder shared.cs folgt. Der Code wird dann automatisch von Visual Studio 2010 auch in die Silverlight Anwendung “repliziert”. In meinem Beispiel validiert laut debugger zwar die Silverlight Anwendung aber der Benutzer sieht keine Fehlermeldung. Das muss man erst über einen optionalen Parameter im ValidationResult ansteuern. Dabei wird der Feldname als Parameter angegeben, hier eben Region. Public Shared Function hannesValid(ByVal region As String) As ValidationResult If region.Length > 2 Then Return New ValidationResult("nur 2 Zeichen", New String() {"Region"}) Denkbar ist auch, da als Array vorhanden, mehrere Felder anzugeben in der Form New String() {"Region", "Phone"}) Sinnvoller ist meines Erachtens einen universellen Silverlight Fehlerchecker zu haben. Dazu wird der Context des auslösenden Controls mitgebeben. Public Class regeln Public Shared Function hannesValid(ByVal region As String, ByVal ctx As ValidationContext) As ValidationResult If region.Length > 2 Then Return New ValidationResult("nur 2 Zeichen", New String() {ctx.MemberName}) Das alles und viel mehr lernt man in meine Silverlight Schulungen bei ppedv.