.
Anmeldung | Registrieren | Hilfe

.NET-Blogs Archiv November 2009

BizTalk: unexpected token ';'

30.11.2009 22:03:00 | Wolfgang Kluge

Ein Kunde kam heute mit einer Orchestration zu mir, die folgende Fehlermeldung beim kompilieren erzeugte:

Error X2016: unexpected token ';'

Wie so oft führt auch hier eine eigentlich extrem kleine Ursache zu dieser Auswirkung. Die Fehlermeldung sagt leider nicht viel aus. Nach kurzer Suche im .odx-Quelltext findet man dann aber zum Glück schnell ein Konstrukt wie

variableName =  ;

Das sieht nicht nur seltsam aus, sondern ist natürlich auch falsch... Grund war in diesem Fall ein einzelnes Leerzeichen als "Initial Value" der System.String-Variable. Das ist fast schon "fies", da man den Fehler nicht einmal auf den ersten Blick auf die Eigenschaften der Variable erkennen kann (wie im Screenshot zu sehen).

BizTalk Server Orchestration-Fehlermeldung unexpected token

Für string-Variablen muss jeder Initialwert also stets in doppelten Anführungsstrichen stehen.

SharePoint Adventskalender

30.11.2009 18:10:00 | Thorsten Hans

Advent, Advent ein Lichtlein brennt, erst eins dann zwei …..

Für alle deutschen SharePoint Interessierten wird die gesamte Adventszeit eine einzige Bescherung werden, denn jeden Tag werden wir auf dem extra zu diesem Zweck eingerichteten SharePoint 2010! Blog einen Post zum Thema SharePoint 2010 veröffentlichen.

SharePoint Adventskalender Für die einzelnen Adventssonntage haben wir uns jeweils noch eine kleine Überraschung ausgedacht… Die Weihnachtszeit sollte ja nicht so langweilig ausfallen.

Den SharePoint Adventskalender könnt Ihr unter http://www.sharepointadvent.com erreichen.

Als Initiator der Idee möchte ich bereits an dieser Stelle allen Mitwirkenden herzlich Danken, 24 Posts in 24 Tagen ist ja ne Menge Holz :) aber dass wird schon…

Ein weiterer Dank gilt noch meinem Arbeitgeber der Data One GmbH die sowohl die Domain als auch das Hosting gesponsort hat.

 

 

DotNetKicks-DE Image

IronRuby - .NET 3.5 vs .NET 4.0

30.11.2009 12:08:13 | Thorsten Hans

Dynamic ist eines der neuen Features in .NET 4.0! Anhand eines kleinen Beispiels möchte ich die Vorteile von dem dynamic Type zeigen.

Zunächst ein einfaches IronRuby Script wie man es unter .NET 3.5 schreiben würde.

 

var engine = IronRuby.Ruby.CreateEngine();
engine.Execute(@"class Calculator 
                                def Calc 
                                    21*2 
                                end 
                            end");
object calculator = engine.Execute("Calculator.new");
Console.WriteLine(engine.Operations.
               InvokeMember(calculator, 
                                       "Calc",
                                       new object[]{}));

 

Zum direkten Vergleich hier das gleiche mit .NET 4.0 und dynamic

var engine = IronRuby.Ruby.CreateEngine();
engine.Execute(@"class Calculator 
                                def Calc 
                                    21*2 
                                end 
                            end");
dynamic calculator = engine.Execute("Calculator.new");
Console.WriteLine( calculator.Calc());

 

Wie man sieht liegt der Unterschied im Detail, da die Validierung der Dynamic Instanz erst zur Laufzeit geschieht, benötigt man ab .NET 4.0 die Hilfsmethoden der IronRuby Engine nicht mehr. Dadurch wird der Code lesbarer und kann somit auch leichter gewartet werden.

Da wie bereits erwähnt die Validierung des Dynamic Codes erst zur Runtime ausgeführt wird, kann VisualStudio natürlich auch keinen IntelliSense bieten. Hierbei kommt aber die neue Version des ReSharpers ins Spiel. Aktuell ist die Visual Studio 2010 Version des ReSharpers über das JetBrains TAP Programm verfügbar.

 

Technorati-Tags: ,,
DotNetKicks-DE Image

Umfrage: Zieht DDD eine deutsche Benennung für Klassen und deren Member nach sich?

27.11.2009 19:35:16 | Andre Kraemer

Bis vor kurzem hätte ich die Frage, ob Klassen, Methoden, Eigenschaften und Variablen innerhalb eines Quellcodes Deutsch oder Englisch benannt werden sollen ohne zu zögern mit "Natürlich Englisch" beantwortet.

Mittlerweile bin ich mir dessen nicht mehr so sicher. Seit einiger Zeit befasse ich mich nun mit Domain-Driven-Design und damit verwandten Themen. In der meist englischen Literatur bzw. Blog Beiträgen wird stets darauf hingewiesen, dass man im DDD komplett in die Domäne des Kundens eintauchen und dessen Sprache sprechen sollte.

So schreibt Gojko Adzic zum Beispiel in seinem Buch Bridging the Communication Gap, dass man als Entwickler nicht mit technischen Bezeichnungen arbeiten und diese für den Kunden übersetzen, sondern durch das ganze Projekt hindurch die (Geschäfts-)sprache des Kundens nutzen soll.

Gerade im englischsprachigen Raum kann ich mir dies auch problemlos vorstellen. Wenn bei meinen Kunden ein Artikel in einer Bestellung zum Beispiel OrderItem genannt wird, hätte ich auch kein Problem damit, eine Klasse OrderItem in meinem Code anzulegen. Auch Methoden wie GetOrderItemById, oder GetOrderItemByName würde ich ohne zu zögern in einem Repository unterbringen.

Was aber, wenn wir im deutschsprachigen Raum arbeiten? Der domänenspezifische Begriff des Kundens wäre zum Beispiel Bestellposition.

Heißt dies nun, dass ich eine Klasse Bestellposition anlegen sollte? und ein BestellpositionenRepository? Mit den Methoden GetBestellpositionById und GetBestellpositionByName?

Für mich persönlich klingt dies unheimlich grausam. Natürlich könnte ich die Methoden auch HoleBestellPositionAnhandDerId oder HoleBestellPositionAnhandDesNamens nennen. So würde die vermischte Schreibweise zumindest entfallen. Trotzdem würde ein solcher Code, der englische Schlüsselwörter mit deutschen Klassen und Membern vermischt, eigenartig und fremd auf mich wirken.

Auf der anderen Seite habe ich auch schon genug Situationen erlebt, in denen man das korrekte englische Wort zum Domänenbegriff des Kundens einfach nicht kannte. Also ging man schnell zu leo, um dort eine Übersetzung nachzuschlagen. Ergebnis war dann häufig, man entweder eine unpassende und eher komische Übersetzung benutzte, oder aber andere Entwickler gar nicht wussten, was dieser eigenartige englische Begriff bedeuten könnte. Im schlimmsten Fall ging ein anderer Entwickler also auch zu leo und suchte sich dort eine andere Übersetzung heraus. So habe ich zum Beispiel mehrere Jahre in einem Projekt gearbeitet, in dem für den Deutschen Begriff Artikel die englischen Begriffe Article, Part und Material genutzt wurden. Wie man sich vorstellen kann, trug das nicht gerade zur Lesbarkeit des Codes bei.

Von daher meine Frage an die Community: Wie geht ihr in deutschen Projekten vor? Deutsche Namen? Englische Namen? Beides wild gemischt?

Über zahlreiche Kommentare oder auch Blogantworten würde ich mich sehr freuen!



blog.codemurai.de © André Krämer |Impressum | Abonieren

Stellt euch vor… in einer multithreading Umgebung serverseitig Dokumente mit dem Open Xml SDK erstellen

27.11.2009 00:01:00 | Jan Christian Selke

Aber was passiert, wenn die zu erstellenden Dokumente auf einmal GROß werden? Die Antwort ist einfach: Mit etwas Pech, nichts…
Denn das Open Xml SDK ist nicht vollständig threadsafe! Weshalb es so ist und welche Möglichkeiten dem zu entgehen existieren, zeige ich im Weiteren auf.

Der Grund

Das OpenXml SDK nutzt die Klassen Package und PackagePart aus dem Namensraum System.IO.Packaging. Bis zu einer PackagePart Größe von etwa 10 Mb werden die Daten in einem MemoryStream bearbeitet. Ab 10 Mb wird in den IsolatedStorage ausgelagert und die IsolatedStorageFile Klasse ist nicht mutlithreading fähig.
Bei parallelen Zugriffen auf mehrere Parts mit Größen  > 10Mb (sowohl schreibend als auch lesend), wird der Memory Stream also in den IsolatedStorage ausgelagert. Jetzt kann es passieren, dass innerhalb eines Threads nativer Code auf einen win32 mutex wartet, während ein CLR lock auf dem IsolatedStorageFile Objekt gehalten wird. Ein zweiter Thread wartet darauf ein CLR lock zu erhalten, um den win32 mutex zu lösen - ein klassisches Deadlock Szenario ist geschaffen.

Die Erkenntnis

Mit welchem Kammerjäger wir dem “Käfer” zu Leibe gerückt sind, wird André Krämer demnächst in seinem Blog im Rahmen einer weiteren Folge seines WinDbg Tutorials erklären.
Um den Käfer aus seinem Versteck zu locken, habe ich eine Testanwendung geschrieben. Nach eingehender Analyse des Fehlerbildes wurde klar, dass er nur im Kontext großer Dokumente reproduzierbar war. Bis zur Reproduzierbarkeit habe ich den Mainpart eines Dokuments mit lorem ipsum sukzessive auf bis zu 12 Mb aufgefüllt.
Der Test basierte noch auf dem Open Xml SDK 1.0, die parallelen Threads habe ich wie folgt gestartet:
internal void StartDeadlockDemo()
{
    var workerThread = new Thread[this.threadCount];
    for (int i = 0; i < threadCount; i++)
    {
        string individualDocumentPath = string.Format(
            "{0}{1}{2}.docx",
            Path.GetDirectoryName(this.wordDocumentPath),
            Path.GetFileNameWithoutExtension(this.wordDocumentPath),
            i);
        File.Copy(this.wordDocumentPath, individualDocumentPath, true);
        workerThread[i] = new Thread(this.UpdateDocumentWithoutAnySense);
        workerThread[i].Start(individualDocumentPath);
    }
}

Die Threads öffnen das Dokument, laden den Mainpart in ein Xml Dokument und speichern das Xml Dokument zurück in den Mainpart.
private void UpdateDocumentWithoutAnySense(object fullWordDocumentFileName)
{
    using (var wordprocessingDocument = WordprocessingDocument.Open((string)fullWordDocumentFileName, true))
    {
        var xmlDocument = new XmlDocument();
        xmlDocument.Load(wordprocessingDocument.MainDocumentPart.GetStream(FileMode.Open, FileAccess.Read)); 
        using (var documentStream = wordprocessingDocument.MainDocumentPart.GetStream(FileMode.Open, FileAccess.Write))
        {
            documentStream.Seek(0, SeekOrigin.Begin);
            documentStream.SetLength(0);
            xmlDocument.Save(documentStream);

            documentStream.Flush();
            documentStream.Seek(0, SeekOrigin.Begin);
        } 
    }
    if (SavingsDone != null)
    {
        SavingsDone();
    }
}

Eine kleine Änderung macht deutlich, dass es sich um kein Xml, sondern ein allgemeines Open Xml Problem handelt. Nach Ersetzen des Speicheraufrufs gegen den Folgenden, werden nur noch Objekte des Open Xml SDK 2.0 genutzt.
private void UpdateDocumentWithoutAnySense(object fullWordDocumentFileName)
{
    using (var wordprocessingDocument = WordprocessingDocument.Open((string)fullWordDocumentFileName, true))
    {
        wordprocessingDocument.MainDocumentPart.Document.Save(wordprocessingDocument.MainDocumentPart);

    }

    if (SavingsDone != null)
    {
        SavingsDone();
    }
}

Auch hier zeigt sich das gleiche Fehlerbild.

Mögliche Lösungen

Die erste Möglichkeit besteht in einem grundsätzlichen Serialisieren aller Speicheraufrufe. Es müssen critical sections für jeden Speicheraufruf definiert werden, die immer von genau einem Thread betreten werden können. C# bietet hierzu das lock Statement. Ein anderer guter und verständlicher Artikel zum lock Statement findet sich bei dotnetphen.com.
    using (var wordprocessingDocument = WordprocessingDocument.Open((string)fullWordDocumentFileName, true))
    { 
        lock(syncObject)
        {

            wordprocessingDocument.MainDocumentPart.Document.Save(wordprocessingDocument.MainDocumentPart);
        }

    }

Da die Sperre über alle Instanzen gültig sein soll, wird das Synchronisationsobjekt als statische  Instanzvariable deklariert.
private static readonly object syncObject = new object();
Der Nachteil dieser Lösung liegt in der Serialisierung. Der große Performanzvorteil der parallelen Dokumenterstellung auf dem Server wird ausgehebelt, wenn jeder Zugriff auf einen Part serialisiert werden muss. Es kann zu einer Art “Stau” der Aufrufe führen.
Eine weitere Alternative ist der Einsatz der ZIP Klassen der J# Libraries. In diesem Fall müsste die komplette Zugriffslogik für das Auslesen und Speichern der docx als Zip Datei eigenständig implementiert werden. Meines Erachtens ein unnötiger Ansatz, dass Rad neu zu erfinden…
Eine nicht ganz saubere, aber funktionierende dritte Alternative habe ich gewählt. Eine konfigurierbare HighWaterMark wird gesetzt, welche der maximal zulässigen Größe der Stream Eigenschaft Length entspricht. Überschreitet die Länge des Streams diese, werden die Speicher und Lese-Aufrufe in eine critical section umgeleitet. Andernfalls wird weiterhin parallel verarbeitet. Zuerst wird geprüft, ob diese Marke für den zu speichernden Part überschritten ist.
private void CheckForPossibleDeadlockSzenario(XmlDocument newXmlMainDocumentPart)
{
    using (Stream mainDocumentStream = new MemoryStream())
    {
        newXmlMainDocumentPart.Save(mainDocumentStream);
        StreamOperationsRequireLock = (Settings.Default.DocumentSizeHighWaterMark < mainDocumentStream.Length);
    }
}

Dann erfolgt die Auswertung in der speichernden Methode. Ist die Marke überschritten, wird eine exklusive Sperre vergeben.
CheckForPossibleDeadlockSzenario(newXmlMainDocumentPart);
if (StreamOperationsRequireLock)
{
    Monitor.Enter(lockObj);
}

In einem try…finally-Block um die Methodenaufrufe wird sichergestellt, dass der Monitor auch wieder freigegeben wird.
try
{
    this.EnterThreadMonitorIfRequired(newXmlMainDocumentPart);
    …
}
finally
{
    this.ExitThreadMonitorIfRequired();
}

Es mag elegantere Lösungen geben. Die Schwierigkeit liegt aber in der Fragestellung: Woher weiß ich, wie groß der Stream als Datei wird, solange er noch nicht als Datei gespeichert ist?

Speaker @ Windows Azure Launch Day 2009 in Stuttgart

26.11.2009 20:31:18 | Jan Schenk



tweetmeme_url = 'http://blogs.msdn.com/jansche/archive/2009/11/26/speaker-windows-azure-launch-day-2009-in-stuttgart.aspx'; tweetmeme_source = 'jansche';

Ich war dabei!

Nachdem letzte Woche der offizielle “ready-for-production”-Start der Windows Azure Platform auf der PDC2009 bekannt gegeben worden ist - oder aber auch nicht, nachdem bis Ende Januar 2010 nicht abgerechnet wird – hat auch Deutschland heute sein Launch-Event gehabt. Das ganze hat in Stuttgart, genauer gesagt im STEP (Stuttgarter Engineer Park), stattgefunden und war ein sehr schönes, großes Event. Es waren mehr als 200 Teilnehmer aus BusinessIT und Entwicklern.

Ich selber habe einen kurzen Vortrag über Cloud Computing und Devices gehalten, der mich fast noch meinen letzten Nerv gekostet hätte. Morgens im Zug (ICE610) musste ich feststellen, dass ich in mein Azure-Konto keine neuen Projekte mehr veröffentlichen konnte. Das lag daran, dass ich einen LiveID-Kontoumzug vornehmen musste, da meine alte LiveID mit microsoft.com-Domäne nicht mehr akzeptiert wurde. Das kam nicht überraschend, ich wurde im Vorfeld darauf hingewiesen, allerdings dachte ich, dass meine Tokens mitumgezogen würden. Ein kurzer Hilfeschrei an den Windows Azure-Verteiler im Microsoft Netzwerk hat mir aber den ersehnten neuen Token gebracht. Danke an Steffen “TokenGod” Weh, der mich vor einer Katastrophe bewahren konnte.

Dann musste ich feststellen, dass meine Applikation für mein Windows Phone Gerät, keine Webservices konsumieren konnte, weil im von Windows Azure zurückgelieferten WSDL die falschen URIs hinterlegt wurden. Hier hat mich Holger Sirtl auf dem Launch Day vor schlimmerem bewahrt. Dank seiner Hilfe konnte ich die Datei Reference.cs händisch modifizieren.

Der Rest lief dann ganz gut, ich denke, dass die Botschaft “Cloud everywhere” angekommen ist.

Aber Leute, so eine Device-Show ist einfach nichts für mich. Da erzähle und erkläre ich lieber anhand von gut funktionierenden Beispielen.

Ich bin dank dem Stress der Vorbereitung gerade mal dazu gekommen ein (1) Bild von der Veranstaltung zu schiesssen.

Und, das muss man Tim Fischer und der ganzen Crew vor Ort lassen, die Veranstaltung, die Location und die gesamte Technik waren erhaben! Das hat wirklich Spass gemacht. Bühne, Musik, Anmoderation, Kamera, alles hat funktioniert und war stimmig. Daumen hoch dafür.

CIMG0959

Also dann, ihr lieben IT-Entscheider und Entwickler, nun ist es an euch Windows Azure zu dem zu machen, was es im Konzept schon ist. Everywhere!

Viele Grüße aus dem Zug (ICE691) nach München!
jan

Autorefresh div mit ASP.NET MVC und jQuery

26.11.2009 13:48:24 | Thorsten Hans

Dieser Teilbereich der Webseite muss im Intervall von X Sekunden neu geladen werden!

Diese oder ähnliche Aussagen kennt bestimmt jeder Webentwickler! Mit ASP.NET MVC und jQuery lässt sich dieses Szenario schnell und einfach erstellen.

Datenbankebene

Das Szenario lässt sich einfach anhand eines Newstickers darstellen. Angenommen das DBMS beinhaltet eine Entität für Nachrichten die wie folgt aussieht

DBMS_News

Schema der News Tabelle

 

Als DataAccessLayer für diese Tabelle kann eine beliebige Technik wie zum Beispiel

  • NHibernate
  • LinqToSql
  • Entity Framework

order andere verwendet werden. Zur Realisierung der oben genannten Anforderung sollten alle NewsTitel in einer Tabelle dargestellt werden.

Die View (Part 1)

Gemäß DRY (Don’t repeat yourself) erstellt man nun eine partielle View die die geforderte Tabelle Rendert.

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<RefreshMe.Models.NewsEntry>>" %>
    <h2>aktuelle News</h2>
     <table class="list">
        <tr>
            <th>
                Titel
            </th>
            <th>
                Autor
            </th>
            <th>
                Datum
            </th>
        </tr>
 
    <%  int i = 0;
        foreach (var item in Model) { %>
        <tr class='<% if (++i % 2 == 0) { Writer.Write("list-alternate"); }%>'>
            <td>
                <%= Html.Encode(item.Title) %>
            </td>
            <td>
                <%= Html.Encode(item.Author) %>
            </td>
            <td>
                <%= Html.Encode("Release") %>
            </td>
        </tr>
    <% } %>
    </table>

 

Nachdem das UserControl erstellt wurde fehlen noch zwei Schritte bis zur fertigen Lösung, die entsprechende Methode auf dem Controller, die immer die aktuellen Daten liefert und die JQuery Komponente, die die Seite aktualisiert.

 

Der Controller

Zunächst die Methode auf dem NewsController. Über das Attribut AccetVerbs wird hierbei angegeben dass nur GET Anfragen von dieser Methode verarbeitet werden, ansonsten ist eigentlich nichts besonderes zu beachten:

[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Refresh()
{
    var news = repository.GetLatestNews();
    return PartialView("Refreshable", news);
}

 

Die View (Part 2)

Zum Schluss nun noch die jQuery Komponente in der gewünschten Site, die im definierten Intervall das UserControl neu lädt.

    <script type="text/javascript">
        $(function() {
            setInterval(function() {
                $.get('<%=Url.Action("Refresh")%>', {},
                        function(view) {
                            $("div#refreshContent").html(view);
                        })
            }, 60000);
        }); 
    </script>
 
    <div id="refreshContent">
        <%Html.RenderPartial("Refreshable", Model);%>
    </div>

 

Was hier geschieht? Nun eigentlich ganz einfach. Zuerst wird das UserControl in ein div gebettet und einmal gerendert

<div id="refreshContent">
   <%Html.RenderPartial("Refreshable", Model);%>
</div>

Die Magie ist in dem kleinen Script Tag zu finden, über die jQuery Methode setInterval() wird alle 60 Sekunden (60000 Millisekunden) eine GET-Anfrage an die entsprechende Methode des Controllers gesendet. Im Erfolgsfall wird nun einfach der HTML-Content des div’s mit der ID “refreshContent” neu geschrieben.

Und schon ist die Anforderung erfüllt und ein Teilbereich der Webseite wird dynamisch jede Minute neugeladen.

 

Fazit

Wie immer mit ASP.NET MVC und jQuery sind die Lösungen schnell entwickelt und leicht verständlich. Auch dieses Beispiel ist wieder ein Grund mehr ASP.NET MVC in Verbindung mit jQuery einzusetzen.

 

Technorati-Tags: ,
DotNetKicks-DE Image

Wie kann ich eine Guid als Datensatz-ID verwenden, wenn in der Datenquelle keine ID vorhanden ist?

26.11.2009 11:50:02 | Klaus Bock

In einem aktuellen Projekt stand ich vor genau diesem Problem. Ich hätte gerne eine eindeutige ID für jeden Datensatz verwendet, aber in der Datenquelle, eine einfache XML-Datei, gibt es keine. Ich könnte ja auch den Titel des Datensatz als ID verwenden, natürlich; aber Leerzeichen in einer ID wiederstreben mir einfach. Den Titel zu normalisieren währe auch eine Möglichkeit, aber ich wollt eine Guid als ID im Repository.

Wie also eine Guid verwenden, wenn in der Datenquelle keine vorhanden ist? Für jeden Datensatz eine erzeugen, ist sicherlich kein Problem. Dann aber erhält jeder Datensatz im Repository bei jedem neu laden der Datenquelle eine andere Guid; auch nicht schön. Ich wollte eine Guid, die eindeutig zu einem Datensatz gehört und bei jedem laden der Datenquelle immer die gleiche Guid zu einem Datensatz erzeugt wird.

Der Titel eines jeden Datensatz ist einmalig. Das war schon mal ein Ansatzpunkt. Also muss irgendwie aus einem Titel eine Guid erzeugt werden.
Wie sieht so eine Guid eigentlich aus? Sie ist lediglich eine gruppierte Hexadezimalziffer, 36 Zeichen lang und mit Bindestrichen als Trennsymbole. Also muss nur irgendwie der Titel, der ja als Zeichenfolge vorliegt, in eine Hexadezimalziffer umgewandelt werden. Das geht einfacher als mancher vieleicht jetzt denkt.

Es wird einfach ein MD5-Hash des Titel erzeugt. MD5 garantiert bei der Hashwerterzeugung immer den gleichen Wert bei gleicher Basiszeichenfolge. Da MD5 ein Array vom Typ byte erzeugt, braucht dieses Array nur noch in eine Zeichenfolge gewandelt zu werden, die als Hexadezimalziffer dargestellt wird. Auch der Umstand, dass MD5 eine Bytearray mit 16 Bytes erzeugt kommt da sehr gelegen. Jedes Byte wird mit der ToString Methode der Byte Struktur als Hexadezimal-Zeichenfolge dargestellt. Bis jetzt ist bereits eine Hexadezimalziffer mir 32 Zeichen erreicht. Jetzt nur noch die Bindestriche an der richtigen Stelle einfügen und die Guid ist fertig.

private static string CreateId(string input)
{
    var sb = new StringBuilder();
    var md5 = new MD5CryptoServiceProvider();
    var hash = md5.ComputeHash(Encoding.UTF8.GetBytes(input));

    // das byte-Array in einen Hex-String parsen
    foreach (var item in hash)
    {
        sb.Append(
			item.ToString("x2", CultureInfo.InvariantCulture));
    }

    // die Bindestriche einfügen
    sb.Insert(8, "-");
    sb.Insert(13, "-");
    sb.Insert(18, "-");
    sb.Insert(23, "-");

    return sb.ToString();
}

So komme ich zu meiner Guid als Datensatz-ID, die XML-Datei bleibt unverändert und ein neuer Blogartikel ist auch dabei entstanden.

Technorati-Tags: | |

Da war doch noch was…

25.11.2009 20:54:00 | Gordon Breuer

Woohoo (Smiley) Im September gab es doch eine Blog-Parade zum Thema “Die drei beliebtesten Bücher aus dem .NET-Umfeld” von Wolfgang Kluge. Und ausgerechnet von mitte September bis anfang November hatte ich mir dann eine kleine Online-Auszeit genommen. Wolfgang blieb aber bis zuletzt hartnäckig und hat mich dann vor ein paar Wochen doch noch endlich erreicht: Ich hab was gewonnen! :-)

Ein wenig enttäuschend war leider die Anzahl der Teilnehmer, eine repräsentative Auswahl an Büchern für den gemeinen .NET-Entwickler kam dabei also leider nicht zusammen. Aber die eine oder andere Anregung habe ich dennoch mitgenommen – und dank Wolfgangs Gutschein werde ich auch dieses Jahr noch auf kleine Einkaufstour gehen damit ich über die Feiertage etwas zum Lesen habe.

Danke an dieser Stelle noch mal an Wolfgang und die anderen drei Teilnehmer mit ihren Lese-Empfehlungen: Stefan Macke, Sven Eiter, und Mario Noack.

msdn tv – Nachrichten für Entwickler (Ausgabe vom 25.11.2009)

25.11.2009 16:37:18 | Jan Schenk



tweetmeme_url = 'http://blogs.msdn.com/jansche/archive/2009/11/25/msdn-tv-nachrichten-f-r-entwickler-ausgabe-vom-25-11-2009.aspx'; tweetmeme_source = 'jansche';

Get Microsoft Silverlight

„msdn tv – Nachrichten für Entwickler“ kommt diesmal aus Berlin und präsentiert u.a. Impressionen und Statements von der „Tech·Ed Europe 2009“. Jan Schenk hatte dort Gelegenheit, als Gesprächspartner Orlando Escalante vor Mikrofon und Kamera zu bekommen, der als „Role Owner“ der Technical Platform Evangelists bei Microsoft mitverantwortlich für die Beratung von IT-Professionals zeichnet.
In den Kurznachrichten: Infos zur Beta des ASP.NET MVC Framework 2.0, eine Tutorial-Reihe rund um ‘Expression Studio‘, die Beta 2 Version von Visual Studio 2010 Ultimate und wo man sie kostenlos bekommt, das neue Facebook .NET SDK 3.0 und eine aktuelle MSDN Webcast-Serie zu ‘Powershell’. Sponsorhinweis: Unser Moderator Jan Schenk wird eingekleidet und ausgestattet von Jan Schenk


Nicht vergessen: Das Expression Studio 3 Gewinnspiel läuft noch bis zum 30.11.2009. Gewinne eine von fünf Microsoft Expression Studio 3 Lizenzen.Einfach diesen Text retweeten:

@jansche RTen und Expression Studio gewinnen! msdn tv - Nachrichten für Entwickler http://msdn-online.de/msdntv #msdntv

Teilnahmebedingungen findet ihr hier: http://www.der-evangelist.de/rechtliches/expression-studio-gewinnspiel-teilnahmebedingungen/


msdn tv ist ein neues Video-Nachrichtenformat, und hat seinen Ursprung auf MSDN Online (http://www.msdn-online.de/msdntv/). Alle zwei Wochen präsentiert Ihnen Jan Schenk, Developer Evangelist mit Hut, die wichtigsten Neuigkeiten für Entwickler, Hintergrundberichte und Interviews zu aktuellen Technologien sowie Highlights von Messen und Konferenzen. Das ganze kompakt, in weniger als 15 Minuten erfrischend jung verpackt , und sowohl als Download für Ihren Rechner oder im Online-Player per Streaming verfügbar.

msdn tv is a German-speaking new and innovative video news series, and has originally been featured exclusively on the German MSDN Online Platform (http://www.msdn-online.de/msdntv/). Hatted Developer Evangelist Jan Schenk biweekly presents latest news for developers, background-stories and interviews concerning current and upcoming technologies, as well as video-highlights from fairs and conferences. Packed into less than 15 minutes, these news videos feature a fresh informative style, and are downloadable as well as available as online streaming video.

Neuer kWh-Logger von EKM installiert

24.11.2009 17:04:00 | Michael Schwarz

Gestern habe ich neue Stromzähler von EKM bekommen. Im Gegensatz zu den anderen Stromzählern, die ich schon letzte Woche ausprobieren konnte, verwenden diese eine Stromzange pro Phase.

EKM kWh-Logger

Stromzange

Das schöne an dem Gerät ist, dass ich neben dem Verbrauch auch die Spannung aufzeichnen kann. Jetzt muss ich nur noch die Daten auslesen, und vernünftig anzeigen. Geplant ist eine Implementierung mit dem .NET Micro Framework. Mal schauen, wie viel Zeit ich diese Woche habe.

Deutsches Windows 7 Kompatibibilitätscenter ist live

24.11.2009 14:36:32 | Peter Kirchner

Die Liste der Anwendungen des deutschen Windows 7 Kompatibilitätscenters basiert auf den Angaben von Softwarepartnern, die bestätigt haben, dass ihre Produkte Windows 7 unterstützen.

Suchen Sie nach Firmen- oder Produktnamen, um die Website des jeweiligen Unternehmens aufzurufen, und kehren Sie regelmäßig zurück, um sich über Aktualisierungen und Ergänzungen zu informieren.

image

Weitere Informationen zum Windows 7 Logo Programm und wie Sie es als Softwarehersteller erhalten können, finden Sie im Windows Developer Center.

Weiterführende Infos zum Thema Windows Anwendungskompatibilität

Webcast --- Außerdem können Sie sich auch einen Einstieg ins Thema verschaffen, wenn Sie sich den folgenden Webcast anschauen: http://www.microsoft.com/germany/MSDN/webcasts/library.aspx?id=1032426804

Workshop --- Alternativ bieten wir dieses Jahr auch noch einmal einen kostenfreien Workshop zum Thema Windows 7 Anwendungskompatibilität in Berlin am 7. Dezember an. Noch haben wir freie Plätze. Eine Anmeldung ist über die Adresse fitmit7@microsoft.com möglich. Infos zum Inhalt des Workshops können Sie auf den Microsoft Partner Network-Seiten. (Eine kostenfreie Anmeldung ist für Nicht-Microsoft-Partner ebenfalls möglich!)

TechTalk --- Unseren TechTalk zu Windows 7, den Oliver Scheer und ich zusammen im Oktober gemacht haben, haben wir aufgezeichnet. Diesen können Sie sich ebenfalls ansehen.

Update ohne Panel mit AJAX.PRO

22.11.2009 22:30:27 | Rene Drescher-Hackel

Kürzlich stolperte ich über einen Beitrag von Roberto Bez, als ich dabei war, einen Blogbeitrag zum Thema Updatepanel & Co zu planen. Es entspricht dabei einer alten Angewohnheit, dass ich zuerst einmal  schaue, ob nicht über dieses Thema schon genug geschrieben wurde, oder ob möglicherweise ein Bedarf da ist. Gut, ich muss eingestehen, zum Thema welches sich mit Ajax.Pro realisieren lässt gibt es im Netz in der Tat nicht viel - im Wesentlichen ja nur Michaels Seite.

Laufzeitfehler 3049 beim Import von Daten in Access 2003

20.11.2009 21:03:00 | Martin Hey

Vor die Aufgabe gestellt, mehrere hundert csv-Dateien analysieren, hab ich mich dafür entschieden, diese in eine Access-Datenbank zu importieren. Access bietet die integrierte Funktion DoCmd.TransferText, um CSV-Daten einfach einzulesen. Also schnell einen Fünfzeiler geschrieben, der durch alle Dateien des Ordners iteriert und für jede Datei DoCmd.TransferText aufruft.

Nach einigen Durchläufen bekam ich allerdings "Laufzeitfehler 3049" mit der vielsagenden Meldung "Datenbank '' konnte nicht geöffnet werden".
 Aber welche Datenbank eigentlich? Ich importiere doch aus Textdateien und wieso steht da eigentlich kein Name? Glücklicherweise bietet mir der Dialog ja die Möglichkeit, zu debuggen. Und einmal im Sourcecode konnte ich auch schnell herausfinden, welche Datei gerade importiert werden soll - vielleicht hatte ja nur der Entwickler der Funktion im Office-Team vergessen, den Dateinamen mit auszugeben. Die Datei war dann auch schnell im Dateisystem gefunden und ich öffnete sie, um sie zu prüfen. Ergebnis: Sie war nicht gesperrt und auch im richtigen Format.

Nach einiger Zeit kam ich dann auf die rettende Idee: Vielleicht handelt es sich ja wirklich um eine Datenbank und nur der Rest der Fehlermeldung ist verwirrend. Eine Prüfung der Access-Datenbank zeigte: Die Datei war mittlerweile an die Grenzen ihrer Möglichkeiten gelangt und zu einer Größe von 2 GB angewachsen. Da diese Größe bei mir hauptsächlich daraus resultierte, dass ich zuvor einen Testlauf durchgeführt hab und zwischendurch nicht komprimiert hatte, konnte ich das Problem sehr schnell lösen durch einen Aufruf von Datenbank komprimieren und reparieren.

Problem gelöst - aber: Eine aussagekräftigere Fehlermeldung hätte mich schneller zum Erfolg gebracht....

Q/A Mergen und Verlinkung von WorkItems mit VS2010

20.11.2009 17:15:47 | Christian Binder

Folgende gute Frage habe ich zum Thema Version Control bekommen:

“Es gibt zwei Branches (z.B. trunk, release). Ich checke ein ChangeSet auf release ein und verlinke dabei ein WorkItem. Mit dem TFS 2008 muss man nun zur Wahrung der WorkItem-Zuordnung, vor allem beim Annotate, jedes ChangeSet einzeln hochmergen und dabei jeweils wieder das relevante WorkItems verlinken. Besteht beim TFS 2010 nun die Möglichkeit das beim Mergen eines bzw. vieler ChangeSets die jeweils verlinken WorkItems mit dem gemergten Resultat automatisch verlinkt sind. Also kann ich dann bei einem Annotate auf trunk das ursprünglich auf dem Branch release verlinkte WorkItem finden?”

Ich habe die Frage mal mit folgendem Beispiel versucht zu beantworten:

Folgende Branch Struktur:

clip_image001

In FeatureCCValidation habe ich 2 Chg’s (29 und 30) durchgeführt und jeweils mit ein Bug verknüpft:

clip_image002

Danach beide Chg’s via RI nach Main ge-merged:

clip_image003

Der Merge  nach Main in im ChgSet31:

clip_image004

Click auf das ChgSet 31 zeigt welche Ressourcen ge-merged wurden:
clip_image005

Öffne ich nun in Main das CCValidation.cs file, kann ich mit dem History view alle Chg‘s am File sehen, auch über Branches hinweg:

clip_image006

Wenn ich Chg 31 mit Annotate anschaue, sehe ich die ursprüngliche Chg’s aus der Feature Branch (Chg29 und 30) für die entsprechenden Codezeilen:

clip_image007

Und von dort kann ich auch die ChgSet Details zugreifen, die auch die ursprünglich assoziierten Work items zeigen:

clip_image008

Chris

Aufzeichnung vom Windows 7 TechTalk Oktober 2009

20.11.2009 12:11:00 | Oliver Scheer

Der Hauptfokus bei Windows 7 wurde auf die weitere Verbesserung der Sicherheit, Zuverlässigkeit und Performance des Betriebssystems gelegt - und auf die größtmögliche Kompatibilität zu Windows Vista , damit bereits bestehende Anwendungen auch in Zukunft laufen. Für Entwickler bietet Windows 7 viele neue Schnittstellen, um Anwendungen mit umfassenderen Funktionen zu versehen, die dem Endbenutzer eine neue Erfahrung im Umgang mit Software ermöglichen.

In dieser TechTalk-Aufzeichnung erklären Oliver Scheer und Peter Kirchner, wie etwa die neue Taskbar genutzt werden kann, indem die Preview-Ansicht gesteuert, Status-Informationen ausgegeben oder die Sprunglisten nach Ihren  Wünschen angepasst werden können. Wir zeigen neue Möglichkeiten für die Anpassung von  Windows-Diensten, um die Performance des Betriebssystems optimal zu nutzen und demonstrieren die Verwendung der in Windows 7 eingeführten Bibliotheken, um den Zugriff auf Dokumente Ihrer Anwendung zu vereinfachen. Zusätzlich erfährt man, welche Punkte zu beachten sind, um die Kompatibilität Ihrer Anwendung mit Windows 7 sicher zu stellen, wenn diese bereits auf Windows XP oder Windows Vista laufen. Abschließend wird ein Überblick gegeben, welche Änderungen sich im Windows Logo Programm ergeben haben und wie Sie Ihre Anwendung für Windows 7 zertifizieren lassen können.

Allgemeine Information zu den TechTalks:

Die kostenlosen TechTalk-Veranstaltungen sind ein lebendiges Forum zum Wissensaustausch unter Entwicklern und bieten Gelegenheit, "Microsoft zum Anfassen" zu erleben. Microsoft-Experten vermitteln dabei in Vorträgen ihr Wissen und stehen für Diskussionen zur Verfügung. Dabei ist der TechTalk keine überdimensionierte Massenveranstaltung, sondern bietet das angenehme und lockere Umfeld, das den ganz besonderen Reiz eines Entwicklertreffens ausmacht. Alle weiteren Informationen finden Sie unter http://techtalk.ms

Teil 1: http://channel9.msdn.com/posts/kitano/Aufzeichnung-zum-Oktober-TechTalk-Windows-7--ein-berblick-fr-Entwickler-Teil-1/

Teil 2: http://channel9.msdn.com/posts/kitano/TechTalk-Windows-7-Ein-berblick-fr-Entwickler-Teil-2/

Excel aktualisiert nicht Felder mit Funktionen nach Änderungen in der Xml Struktur

19.11.2009 19:31:00 | Jan Christian Selke

(Update 21.011.: über die Attributierung zu gehen war natürlich schon früher möglich, aber nicht die gängige propagierte Lösung)
Anhand eines Beispiels beschreibe ich die Vorgehensweise, wie in Excel eine Aktualisierung durchgeführt werden kann?
Die zur Zeit des Open Xml SDK 1.0 einzig gängige Lösung war das Löschen der Werte von Feldern mit hinterlegten Funktionen. Hierdurch wurde Excel gezwungen die Werte anhand der hinterlegten Formel neu zu berechnen. Mit dem Open Xml SDK 2.0 kann über die typisierten Klassen vorgegangen werden. Eine weitere Vorgehensmöglichkeit werde ich hier aufzeigen.
Die Zellenformel, x:f im Markup, wird durch die Klasse CellFormula repräsentiert. Sie besitzt das Attribut CalculateCell, im Markup ca. Das Attribute ist vom Typ BooleanValue und wird als “1” oder “0” abgelegt.

Formula

Nach der notwendigen Theorie jetzt zum konkreten Coding.
Zuerst muss die Excel Mappe geöffnet werden, wie im Open Xml allgemein üblich.
using (SpreadsheetDocument workbook =
    SpreadsheetDocument.Open(filePath, true))
{

}

Ist das Dokument geöffnet, wird aus dem Workbook das Sheet ausgelesen, das die Formeln enthält. Das Sheet entspricht Tabellenblättern. Ich lese es anhand des Tabellennamens aus.
string relId = workbook.workbookPart.Workbook.Descendants<Sheet>()
    .Where(s => s.Name == "FormelTabelle")
    .First()
    .Id;
WorksheetPart worksheetPart = (WorksheetPart)workbook.workbookPart.GetPartById(relId);

Aus dem Sheet werden Zellen ermittelt, denen eine Formel hinterlegt ist. Die Formeln dieser Zellen werden dann um das Attribute CalculateCell angereichert. CalculateCell bewirkt, dass bei jedem Öffnen der Datei die Werte der Formel neu berechnet werden.
foreach (Cell cell in worksheetPart.Worksheet.Descendants<Cell>()
    .Where(x => x.CellFormula != null))
{
    cell.CellFormula.CalculateCell = BooleanValue.FromBoolean(true);
}

Fügt man nun alle bisherigen Code-Teile zu einem Ganzen zusammen, erhält man einen recht kurzen und kompakten Code.
public void RefreshFormulas()
{
    using (SpreadsheetDocument workbook =
        SpreadsheetDocument.Open(filePath, true))
    {
        WorksheetPart worksheetPart = GetWorksheetPart(workbook.WorkbookPart);
        foreach (Cell cell in worksheetPart.Worksheet.Descendants<Cell>()
            .Where(x => x.CellFormula != null))
        {
            cell.CellFormula.CalculateCell = BooleanValue.FromBoolean(true);
        }
    }
}

private static WorksheetPart GetWorksheetPart(WorkbookPart workbookPart)
{
    string relId = workbookPart.Workbook.Descendants<Sheet>()
        .Where(s => s.Name == "FormelTabelle")
        .First()
        .Id;

    return (WorksheetPart)workbookPart.GetPartById(relId);
}

Jetzt werden bei jedem Öffnen des Dokuments die Werte neu berechnet. Für jeden, der das nicht möchte, bleibt die altehrwürdige Lösung: Löschen der Inhalte. Dazu einfach die Zeile
cell.CellFormula.CalculateCell = BooleanValue.FromBoolean(true);
durch die folgende ersetzen.
cell.Value = null;

Excel doesn’t update cells with formulas after changing values with Open Xml

19.11.2009 19:31:00 | Jan Christian Selke

Using an example, I will describe a possibility on how an update can be performed.

At the time of the Open Xml SDK 1.0 a, if not the, preferred solution was deleting the cell values with Xml and XPath from the sheet. This excel was forced to re-calculate the cell values with the stored formula. As there is the Open Xml SDK 2.0 this approach is no longer necessary. I will introduce one possibility to proceed.

The formula, x:f in markup, is represented by the class CellFormula. It has an attribute CalculateCell, in markup ca. The attribute is of type BooleanValue and stored as the values “1” or “0”.

Formula

Following the theorie, here comes the coding.

First of all the workbook has to be opened. This is as usual done with Open Xml.

using (SpreadsheetDocument workbook =
    SpreadsheetDocument.Open(filePath, true))
{

}

After this is, the worksheet containing the formulas has to be identified and extracted. I am going to get it by it’s name.

string relId = workbook.workbookPart.Workbook.Descendants<Sheet>()
    .Where(s => s.Name == "FormelTabelle")
    .First()
    .Id;
WorksheetPart worksheetPart = (WorksheetPart)workbook.workbookPart.GetPartById(relId);

All cells are determined from the sheet by its formulas provided. The formulas are extended by the attribute CalculateCell. CalculateCell causes excel to re-calculate the values each time the calculation is performed, e. g.at opening the document.

foreach (Cell cell in worksheetPart.Worksheet.Descendants<Cell>()
    .Where(x => x.CellFormula != null))
{
    cell.CellFormula.CalculateCell = BooleanValue.FromBoolean(true);
}

Putting all these snippets together, we got a really short and compact code.

public void RefreshFormulas()
{
    using (SpreadsheetDocument workbook =
        SpreadsheetDocument.Open(filePath, true))
    {
        WorksheetPart worksheetPart = GetWorksheetPart(workbook.WorkbookPart);
        foreach (Cell cell in worksheetPart.Worksheet.Descendants<Cell>()
            .Where(x => x.CellFormula != null))
        {
            cell.CellFormula.CalculateCell = BooleanValue.FromBoolean(true);
        }
    }
}

private static WorksheetPart GetWorksheetPart(WorkbookPart workbookPart)
{
    string relId = workbookPart.Workbook.Descendants<Sheet>()
        .Where(s => s.Name == "FormelTabelle")
        .First()
        .Id;

    return (WorksheetPart)workbookPart.GetPartById(relId);
}

From now on, every time you open up your excel woorkbook, the values will be re-calculated. For anyone who doesn’t want that,the time-honored solution remains. The line

cell.CellFormula.CalculateCell = BooleanValue.FromBoolean(true);

must be replaced by

cell.Value = null;

Dritter Snippet Wettbewerb auf .NET-Snippets.de

19.11.2009 18:32:00 | Klaus Bock

Seit dem 15. November läuft auf .NET-Snippets.de der dritte Snippet Wettbewerb. Jeder der noch bis zum 13. Dezember ein oder mehrere Snippets auf .NET-Snippet.de veröffentlicht, nimmt automatisch am Wettbewerb teil.

Die Snippets sind auf die .NET-Sprachen C#, VB.NET, Delphi.NET und C++.NET sowie ASP.NET beschränkt.

Natürlich gibt es auch interessante Preise einzuheimsen. Auf den Gewinner wartet eine Windows 7 Ultimate Lizenz. Der Zweitplazierte darf sich auf eine Office 2007 Standard Edition freuen. Als dritter bis zum einschließlich sechsten Platz steht noch je eine Lizenz des tangible T4 Editor bereit. Insgesamt gibt es Preise bis zum 12. Platz.

Die Jury zur Bewertung der eingegangenen Snippets setzt sich aus Tim Fischer, Nico Franze und Jan Welker zusammen.

Mehr Details zum Wettbewerb gibt es auf der Wettbewerb Seite von .NET-Snippets.de.

Technorati-Tags: | |

Wann IEnumerable nutzen, wann ICollection und wieso überhaupt IList?

19.11.2009 18:09:00 | Peter Bucher

Es gibt einige Mengen- /  Auflistungstypen in .NET.

Ein kleine Auswahl:

Früher gab es nur nicht generische bzw. keine stark typisierte Collections, die heute nicht mehr verwendet werden sollten,
da immer explizit gecastet werden muss, was umständlich ist und Performance kostet.

Hierfür zitiere ich gerne herbivore aus myCSharp:

ArrayList gehört in die Mottenkiste und sollte wie alle untypisierten Collections aus System.Collections nicht mehr benutzt werden. Verwende stattdessen List<T> und alle anderen typisierten Collections aus System.Collections.Generic.

Ich möchte hier allerdings nicht die verschiedenen Auflistungstypen im Detail anschauen, sondern herausfinden, wann welcher konkreter Typ oder gar das Interface in einer Signatur verwendet werden sollte.

Ein kleines Beispiel:


public void PrintNamesToConsole(List<string> names)
{
    foreach(string name in names)
    {
        Console.WriteLine(name);
    }
}

Dieser Code verwendet List<T> als Argumenttyp, es besteht also eine Abhängigkeit darauf,
d.h. jeder Aufrufer muss hier eine List<T> übergeben, alles andere funktioniert nicht.
Beispielsweise kann hier kein Array übergeben werden, oder eine Collection.

Wenn dann innerhalb der Methode, die das Argument entgegennimmt, nicht einmal
auf spezifische Methoden / Eigenschaften des konkreten Types (List<T>) zugegriffen wird,
ist das noch ein grösser Nachteil, denn man erkauft sich eine Abhängigkeit, ohne das man sie eigentlich benötigt.

Hört sich komisch an?
Eigentlich ist es relativ leicht, wenn wir uns mal die verschiedenen Schnittstellen betrachten, worauf die Auflistungen in .NET aufbauen.

Der eigentliche Kern ist die Schnittstelle IEnumerable bzw. der typisierte Bruder IEnumerable<T>, wobei dort T den Typ der enthaltenen Elemente angibt.

IEnumerable:

public interface IEnumerable
{
    IEnumerator GetEnumerator();
}

IEnumerable<T>:

public interface IEnumerable<T> : IEnumerable
{
    IEnumerator<T> GetEnumerator();
}

Das Interface IEnumerator sieht dann so aus:
(Die generische Implementation IEnumerator<T>, hat zusätzlich eine Eigenschaft vom Typ T über die Eigenschaft Current).


public interface IEnumerator
{
    bool MoveNext();
    object Current { get; }
    void Reset();
}

Anhand der Beispiele ist zu sehen, das IEnumerable / IEnumerable<T> und die dazugehörige Schnittstelle für den
Enumerator beschreibt, das Elemente durchlaufen werden können. Nicht mehr und nicht weniger.

Das Beispiel von oben, könnte wie folgt umgeschrieben werden, um die kleinste Abhängigkeit zu haben und trotzdem
alle Anforderungen funktionieren, denn es muss ja nur eine Auflistung durchlaufen werden, nicht mehr und nicht weniger.

public void PrintNamesToConsole(IEnumerable<string> names)
{
    foreach(string name in names)
    {
        Console.WriteLine(name);
    }
}

Man beachte den geänderten Argumenttyp, der jetzt viel genereller ist.
Jetzt kann die Methode ein string[], eine List<T>, … entgegennehmen, einfach alles das die Schnittstelle IEnumerable<T> implementiert.

Wird eine Unterstützung in der Art von <Auflistung>.Count gefordert, kann die Schnittstelle ICollection<T> angegeben werden, die eine solche Eigenschaft nativ mitbringt.
Zusätzlich beschreibt das Interface (Erst ab der generischen Variante), das ein Element hinzugefügt, die Auflistung geleert, zurückgeben kann ob ein Element exisitert und Elemente entfernt werden können.

Durch LINQ to Objects können praktisch alle Operationen, wie bspw. Anzahl Elemente abfragen, sortieren, filtern, Zugriff über Index, damit und auf dem IEnumerable<T> Typen gemacht werden.
LINQ to Objects ist schnell, sehr schnell sogar. Wird jedoch die höchste Leistung benötigt und bspw. sehr häufig auf die .Count-Eigenschaft zugegriffen,
ist es besser, wenn eine native Unterstützung einer solchen Eigenschaft vorliegt.

LINQ to Objects arbeitet bei Count ungefähr so:

  • Versuche die Auflistung nach ICollection<T> zu casten.
  • Wenn das klappt, rufe die .Count-Eigenschaft ab und gib das Ergebnis zurück.
  • Wenn es nicht klappt, durchlaufe alle Einträge in der Auflistung, zähle die Anzahl zusammen und gib das Ergebnis zurück.

Das Interface IList<T> selber implementiert ICollection<T> – kann also alles auch – jedoch gibt es zusätzlich noch die Möglichkeit nativ per Index zu arbeiten. Also Elemente indexiert abfragen, ein Element an einem bestimmten Index löschen / einfügen.

In den meisten Fällen reicht es also, wenn IEnumerable<T> als Argumenttyp bzw. Rückgabetyp angegeben wird und in den anderen Fällen jeweils das Interface ICollection<T> / IList<T>, je nachdem was benötigt wird.

Es ist zu beachten, das IList<T> nicht alles beschreibt, was List<T> implementiert, bspw. gibt es dann keine Find- / FindAll-Methode, sowie auch keine native Implementierung für das Sortieren.
Mit LINQ to Objects tritt das allerdings in den Hintergrund und so kann man sich im Code von Abhängigkeiten zu den konkreten Auflistungstypen lösen.

Wieso soll man sich überhaupt lösen?

Umso genereller die Argument- oder Rückgabetypen sind, desto flexibler ist die API und es wird nicht mehr öffentlich gemacht, als schlussendlich verwendet wird.
Zusätzlich ist die Abhängigkeit zu einem konkreten Typ weg, was bedeutet das bspw. anstelle einer List<T> einfach irgend eine andere Implementierung von IEnumerable<T> empfangen / zurückgegeben werden kann.

So kann bspw. später eine Auflistung implementiert werden, die bei einem bestimmten Ereignis wie bspw. das Entfernen eines Eintrages, einen Event auslöst, ohne den Argumenttyp zu ändern.

Folgend noch ein paar sehr interessante Beiträge zum Thema:

Snippet-Wettbewerb auf dotnet-snippets.de

19.11.2009 14:31:00 | Martin Hey

dotnet-snippets.de veranstaltet diesen Herbst zum mittlerweile dritten Mal einen Snippet Wettbewerb. Gesucht werden sinnvolle und wiederverwendbare Quelltextausschnitte der .NET-Sprachen C#, VB.NET, Delphi.NET, C++.NET oder ASP.NET. Dabei ist es unerheblich aus welchem Themenbereich das Snippet stammt.
Einsendeschluss ist der 13. Dezember und als Preis winken verschiedene Softwarelizenzen, Hardware und Bücher.
Nähere Informationen zu den Teilnahmebedingungen, der Jury und den Preisen gibt es auf der Seite von .NET-Snippets.

24. Treffen der PASS Regionalgruppe Sachsen am 20.11.2009

19.11.2009 14:01:00 | Martin Hey

Die Ankündigung kommt dieses Mal etwas spät aber sie kommt: Morgen findet das nächste Treffen der PASS Regionalgruppe Sachsen statt. Im Anschluss an eine Einleitung zum Thema SQL Server Sizing soll ein offener Erfahrungsaustausch zum Thema Planung von Datenbanken und Datenbankservern stattfinden.
Beginn ist 17:30 Uhr im IT-Trainingshaus am Waldschlösschen. Nähere Informationen zum Termin und eine Anfahrtsbeschreibung findet man auf der PASS-Seite im Bereich Regionalgruppe Sachsen.

5. Treffen der SharePoint UserGroup Dresden

19.11.2009 11:33:00 | Martin Hey

Am 17.11.2009 gab es mal wieder ein Treffen der SharePoint UserGroup. Inhaltlich stand dieses Mal SharePoint 2010 auf der Agenda. Die große Teilnehmerzahl von 25 zeigte, dass dieses Thema durchgängig auf großes Interesse stößt. In mehreren Präsentationen zeigten Sascha Henning, Torsten Hufsky und ich welche Neuigkeiten es gibt.
Da Sascha im Oktober bei der SharePoint Conference in Las Vegas und Christian im November bei der TechEd Europe in Berlin war, hatten wir auch zwei Teilnehmer dabei, die mit detaillierten Informationen dienen und Fragen beantworten konnten.

Zentraler Inhalt der einführenden Vorstellung war die neue SharePoint 2010 Pie. Anhand von Beispielen erläuterte Sascha, was es genau mit den einzelnen Bereichen auf sich hat und was es zu beachten gibt. Im Anschluss daran haben wir uns die neu sortierte Zentraladministration etwas näher angeschaut und Torsten zeigte wie einfach man Administrationsaufgaben mit Hilfe der PowerShell durchführen kann. Nach einer kurzen Stärkung und der Gelegenheit, sich dabei mit anderen Teilnehmern auszutauschen, gab es noch einen kurzen Überblick über Sachverhalte, die Entwickler mit der neuen Version des SharePoint beachten sollten. Es war ein sehr informativer Abend für alle Teilnehmer.


Passend zum Thema veröffentlichte Microsoft am 18.11. die SharePoint 2010 Public Beta und damit kann nun das Gelernte direkt am System ausprobiert werden.

EclipseTools jetzt für Silverlight verfügbar

19.11.2009 09:00:00 | Oliver Scheer

Das Eclipse Tools für Silverlight (Ecplise4SL) Plug-In ist ein Open Source und Cross-Platform Plug-In für die Entwicklung von Silverlight Anwendungen innerhalb Eclipse. Microsoft hat bei der Entwicklung mit Soyatec, einem französischen IT Solution Provider, zusammen gearbeitet.

Ab sofort steht die finale Version 1.0 zur Verfügung. Diese Version adressiert Silverlight 2.0 und kann hier herunter geladen werden: http://www.eclipse4sl.org/

Die Roadmap für die Weiterentwicklung kann hier eingesehen werden: http://www.eclipse4sl.org/#roadmap. Ein Video Demo Walkthrough des Plug-In gibt es hier und hier (Mac Version).

image

Eine spätere Wiederherstellung verunmöglichen

19.11.2009 08:56:00 | Michael Schwarz

Das Wort verunmöglichen habe ich noch nie so gehört oder gelesen:

Jede Änderung dieser Partition kann eine spätere Wiederherstellung verunmöglichen.

Dell Wiederherstellungspartition

So gefunden auf einem neuen Dell Studio XPS im vorinstallierten Windows Vista. So wie es der Duden schreibt, ist das wohl eine Schweizer Variante von unmöglich machen.

Wie das Kaninchen vor der Schlange

17.11.2009 21:14:00 | Jan Christian Selke

Zu sagen, dass ich heute vor Ehrfurcht erstarrt bin, als ich Eric White's nunmehr vollendete Serie zum Thema “Transformation of WordprocessingML to XHtml” gelesen habe, ist vielleicht etwas übertrieben. Nicht übertrieben ist, dass es sich um eine fantastische und sehr lehrreiche Reihe handelt. Für jeden Entwickler, der im Kontext Sharepoint und Open Xml tätig ist, handelt es sich fast um ein Muss.

Die einzelnen Posts sind:

1. Transforming Open Xml Word-Processing Documents to XHtml (#1)

2. Transforming Open Xml Word-Processing Documents to XHtml (#2)

3. Transforming Open Xml Word-Processing Documents to XHtml (#3)

4. Open Xml WordprocessingML Style Inheritance

5. Comparison of Html/Css Tables to WordprocessingML Tables

6. Assembling Paragraph and Run Properties for Cells in a Table

Der im Rahmen dieser Serie geschriebene Code wird als Teil der Open Xml PowerTools veröffentlicht. Also, ansehen…

Wer sucht ein Training zu WCF oder Team System?

17.11.2009 16:39:13 | Christian Binder

Wer zu WCF oder Team System noch nach einem guten Training sucht, sollte sich diese Optionen vormerken:

Juval Lowy’s Architect's Master Class in Bad Ems, December 7-11th

Neno’s Team System Camp in Bad Ems, December 14-18th

Juval Lowy’s Advanced WCF Master Class  Feb 8-12

Mehr Infos gibt’s hier: http://www.professional-developer-training.net/Default.aspx

Chris

Blog-Parade: Die 3 beliebtesten Fachbücher aus dem .NET-Umfeld (Ergebnis)

17.11.2009 15:54:00 | Wolfgang Kluge

Nachdem diese Blog-Parade nicht ganz so erfolgreich verlief, wie ich mir das vorgestellt hatte, wird es recht schwer mit Statistiken - weshalb ich an dieser Stelle auch darauf verzichte. Das beliebteste Fachbuch konnte also leider nicht wirklich gefunden werden. Die Liste der vorgestellten Bücher entspricht dennoch der bewerteten Reihenfolge, wobei die Sprache für die Reihenfolge außer acht gelassen wurde.

  1. C# 3.0 Entwurfsmuster / C# 3.0 Design Pattern
     
    von Judith Bishop.
    ISBN: 978-3-89721-867-3(de) bzw. 978-0-59652-773-0 (en)
  2. Clean Code: A Handbook of Agile Software Craftsmanship

    von Robert C. Martin
    ISBN: 978-0-13235-088-4 (en)
  3. Agile Principles, Patterns and Practices in C#

    von Robert C. Martin und Micah Martin
    ISBN: 978-0-13185-725-4 (en)
  4. ASP.NET MVC 1.0

    von Rob Conery, Scott Hanselman, Phil Haack und Scott Guthrie
    ISBN: 978-0-47038-461-9 (en)
  5. Richtlinien für das Framework-Design

    von Krzysztof Cwalina und Brad Abrams
    ISBN: 978-3-82732-626-3 (de)
  6. The Art of Unit Testing

    von Roy Osherove
    ISBN: 978-1-93398-827-6 (en)
  7. Visual C# 2008

    von Frank Eller
    ISBN: 978-3-82732-641-6 (de)
  8. Grundlagen der Anwendungsentwicklung mit dem .NET Framework 2.0

    von Tony Northrup, Shawn Wildermuth und Bill Ryan
    ISBN: 978-3-86645-907-6 (de)
  9. jQuery in Action

    von Bear Bibeault und Yehuda Katz
    ISBN: 978-1-93398-835-1 (en)
  10. Refactoring

    von Martin Fowler
    ISBN: 978-3-82731-630-1 (de)

 

Gewonnen haben alle Teilnehmer. Da es nur 4 waren hab ich mich kurzerhand entschlossen, noch einen weiteren Gutschein mit in die Liste der Gewinne mit aufzunehmen. Ich hab eine kleine Applikation geschrieben, die die Gewinner zieht - und nach diesem Losverfahren kamen folgende Plätze zustande:

  1. Gordon Breuer / anheledir.NET hat den Gutschein über € 40 gewonnen
  2. Stefan Macke / Stefans Blog hat den Gutschein über € 20 gewonnen
  3. Sven Eiter / Svens Blog hat einen Gutschein über € 10 gewonnen
  4. Mario Noack / .NET und PDF Software hat das Buch gewonnen

Glückwunsch nochmal...

PHP Interop: “PHP und Silverlight im Zwiegespräch” Artikel im PHPJournal und kostenlos zum Download

17.11.2009 15:39:01 | Jan Schenk



tweetmeme_url = 'http://blogs.msdn.com/jansche/archive/2009/11/17/php-interop-php-und-silverlight-im-zwiegespr-ch-artikel-im-phpjournal-und-kostenlos-zum-download.aspx'; tweetmeme_source = 'jansche';
SL-PHP_Zwiegespraech

In der aktuellen  Ausgabe des PHPJournal ist ein Artikel von mir veröffentlicht worden, der sich um die Interoperabilität zwischen PHP und Silverlight dreht. “Wo liegt da das Problem?” höre ich euch schon lamentieren, und prinzipiell habt ihr natürlich recht. Es gibt keinen Grund, warum diese zwei Technologien nicht zusammen arbeiten sollten. Dass das aber die wenigsten wissen, ist schon der erste und beste Grund, einen Artikel zu dem Thema zu schreiben.

Und jetzt kommt es faustdick! Der Artikel ist wie schon der vorherige wieder kostenlos herunterladbar. Unter diesem Link http://www.phpjournal.de/media/6-2009/silverlight-php.pdf findet ihr die PDF-Version.

 

Viel Spass beim schmökern,
jan

Add-Ons und Tools fuer die Webentwicklung mit IE8

17.11.2009 10:35:48 | Kay Giza

Für Microsoft und auch mich ist eine ereignisreiche Woche in Berlin zu Ende gegangen. Ich konnte am Internet Explorer 8-Stand der Tech•Ed Europe 2009 sehr viele aufschlussreiche Gespräche und Diskussionen führen. Auch wurde ich mit vielen interessanten Fragen konfrontiert, unter anderem, welche Add-Ons und Tools für die Webentwicklung rund um Internet Explorer 8 zur Verfügung stehen. Es gibt natürlich zahlreiche, fangen wir mit einer kleiner - aber wichtigen - Auswahl an. Als erstes muss man hier natürlich auf die integrierten Internet Explorer Developer Tools hinweisen, die man über das Extras-Menü oder F12 erreicht. Zusammen mit dem Web Debugging Proxy Fiddler erhalten Webentwickler umfangreiche Möglichkeiten. Ebenfalls zu empfehlen ist das User Agent Picker Add-on (UAPick), mit dem Sie unter anderem den User Agent String innerhalb von Sekunden ändern können, ohne dabei den Internet Explorer neu zu starten. Sehr hilfreich ist es weiterhin, mit dem Internet Explorer Compatibility Test Tool (IECTT) in Echtzeit Ihre Webseiten und Webanwendungen auf Kompatibilitätsprobleme zu überprüfen. Zusätzlich können Sie mit Expression Web SuperPreview die Darstellung Ihrer Webseiten in mehreren Browser (z.B. IE6, IE7, IE8 oder Firefox) gleichzeitig überprüfen.

Des Öfteren wurde ich auch nach IE8-Befehlszeilenparametern gefragt, mit denen man u.a. den InPrivate- oder den Kiosk-Modus von Internet Explorer direkt starten kann. Ich verspreche, ich werde die Woche entsprechend Revue passieren lassen und alle interessanten Themen, offenen Fragen sowie Tipps und Tricks in meinem Weblog (in der IE8 Kategorie) sowie im Internet Explorer Developer Center auf MSDN Online veröffentlichen. Und sollten Sie jetzt Interesse an der Add-On-Entwicklung bekommen haben, so werfen Sie doch einfach einen Blick auf das SpicIE-Framework oder in die Internet Explorer Add-On-Gallery.

Soweit so gut erst mal, mal schauen, wie ich die ganzen Notizen und Fragen sowie Hinweise aufarbeite, vielleicht in einer täglichen FAQ? Mal schauen :-)
Apropos Fragen, ich überlege derzeit, wie und in welcher Forum ich die auf der TechEd verteilten Ressource Kits (auf DVD und USB-Sticks) hier zu Verfügung stellen kann. Stay tuned!

Gerne besuchen Sie auch das Internet Explorer Forum auf MSDN und diskutieren Sie Ihre Frage mit der Community!
Mehr demnächst!



This post is powered by www.Giza-Blog.de | Giza-Blog.de: RSS Feed
Visit:  MSDN Online | Follow MSDN Online on Twitter | Follow Kay Giza on Twitter
Daily News on MSDN:  MSDN Aktuell
© Copyright 2006-2010 Kay Giza. All rights reserved. Legal
Subscribe

.NET Micro Framework 4.0 SDKs als Download verfügbar

16.11.2009 20:26:00 | Michael Schwarz

Nach einer recht kurzen Betaphase ist die .NET Micro Framework Version 4.0 bereits fertig. Neu hinzugekommen sind folgende Features:

  • HTTP and HTTPs: An object model is now provided for handing both HTTP clients and servers, similar to the .NET Framework, with the new types System.Net.HttpWebRequest, System.Net.HttpWebResponse, and System.Net.HttpListener from assembly System.Http.dll
  • Multi-touch: Basic support for multi-touch events, such as moving two fingers on a touch screen, is now provided in the object model and the emulator. Gesture support has been redesigned to be faster and more flexible.
  • Versioning: Versioning has been implemented to strictly identify assemblies by the version number at build time and on the device, and eventually re-deploying missing assemblies. Side-by-side load and bind for types belonging to the same assemblies with a different version number is supported. Support has also been added for assembly naming which includes the version number.
  • Emulator support for SSL and HTTPS: The emulator now explicitly supports SSL and HTTPs emulation.
  • Native XML Parser: The XML parser has been moved to native code for better performance.
  • Native collections: The collection classes have been moved to native code for performance, and have been enriched with Queue and Stack types.
  • Time sync: Devices can use the new Time Sync API to sync the system time with a specified server's time, automatically or manually.
  • Arbitrary display size: A custom heap and allocation area is now provided to support bitmaps larger than 760KB.
  • Large buffers: A new type, Microsoft.SPOT.Hardware.LargeBuffer, is provided for allocating buffers larger than 760KB, which would not fit in the managed heap.  This type is located in assembly Microsoft.SPOT.Hardware.
  • Watchdog and Power Level control: The power level and the watchdog behavior can now be controlled from the managed application using types Microsoft.SPOT.Hardware.PowerState and Microsoft.SPOT.Hardware.Watchdog from assembly Microsoft.SPOT.Hardware.dll.
  • Thick pens and gradient fills: A richer graphic model is now provided for designing widgets and controls.
  • TinyCore performance improvements: TinyCore performance has been enhanced in the area of event dispatching and layout.

Wow, das ging ja richtig schnell. Weitere Informationen gibt’s hier.

Silverlight WOW!-Effekte – Vortrag auf der webtech 2009 in Karlsruhe

16.11.2009 20:10:52 | Jan Schenk



tweetmeme_url = 'http://blogs.msdn.com/jansche/archive/2009/11/16/silverlight-wow-effekte-vortrag-auf-der-webtech-2009-in-karlsruhe.aspx'; tweetmeme_source = 'jansche';

Heute war ein guter Tag! Zwar bin ich mal wieder für nur einen Vortrag in der Weltgeschichte herumgereist - morgens los, Session geben, abends zurück – aber die webtech 09 in Karlsruhe war und ist gerade auch noch ein schönes Event. Die Location, das Kongresszentrum in KA, kannte ich noch aus Linuxtag-Zeiten, und wie es mir schien einige Aussteller und Projektstände auch. Sehr viel OpenSource-Business, sehr viele freie und auch kleine Projekte haben um Aufmerksamkeit gebuhlt und das Publikum ist offen und freundlich, we man es von dieser Community gewöhnt ist.

Mein Vortrag drehte sich um die “Silverlight WOW!-Effekte, die unter die UI gehen”, und dafür, dass ich im Prinzip immer noch im TechEd-Koma liege, lief das ganze recht rund.Auf meinem Skydrive findet ihr das Slidedeck, das alle wichtigen Links enthält, um mit den Themen Smooth Streaming, Physics Engine bzw Minirealitäten und DeepZoom Eindruck zu schinden.

Sehr schön fand ich an der webtech, dass der Silverlight Day von Sascha Wolter moderiert wurde. Und mit moderiert meine ich, dass Sascha sich vorbereitet hat und jede einzelne Session anmoderiert hat. Ein paar einleitende Worte bewrken manchmal Wunder, so ist der Sprecher nicht in der unangenehmen Situation, sich selbst vorstellen zu müssen. Und Sascha hat sich wirklich vorbereitet. Er hat sogar – und das nehme ich ihm keineswegs übel – einen Kollegen angeschrieben, um ein paar Hintergrundinformationen zu mir zu bekommen, die ich selbst vielleicht nicht veröffentlicht hätte. Na gut, peinliche Details aus meinem Privatleben kamen jetzt nicht zum Vorschein, das könnte mich und den ein oder anderen Sprecher ja doch etwas zu sehr aus der Bahn werfen und für ein schlechteres Gefühl als ohne Anmoderation sorgen. Und das wäre schliesslich nicht Sinn der Sache.

Von den 25 Teilnehmern, die an der Session teil genommen haben, hatte ich zumindest den Eindruck, dass sie der Inhalt meiner Session wirklich interessiert, insofern macht es mir auch nichts aus, vor einer so übersichtlichen Audience zu sprechen. In den meisten Fällen wünscht man sich dann halt doch möglichst viele Besucher. Auf der heutigen webtech fand ich aber, dass das die kleine Zahl der Zuschauer ein ganz besonderes Flair in den Vortrag gezaubert hat.

Genug geredet, hier ein paar Foto-Impressionen von meinem kurzen Karlsruhe-Trip:

CIMG0917 CIMG0920

Ein wunderschönes Bild auf der linken Seite: Der vorübergehende Microsoft-Stand wird von zwei Besuchern mit Macbook Airs belagert. Das Bild rechts zeigt den neuen Microsoft MSDN-Stand mit der neuen Rückwand im Redesign von msdn-online.  

CIMG0927 CIMG0930

Sebastian Grassl mit Sebastian Schürmann, dem Fachbereichsleiter der CHIP Online. Und dann ging es schon wieder heimwärts. Der Karlsruher Hauptbahnhof hatte auch noch die ein oder andere Hübschhässlichkeit zu bieten.

CIMG0934

So zum Beispiel dieses Bild des Neonlicht-beleuchteten Bahnsteigs. Ach du treue Bahn, wie kommst du nur aus deinem schlechten Klischee wieder raus, wenn deine Bahnsteige nicht mehr zu bieten haben als grünlichtigen Siff? Jetzt kosten die deine Tickets schon so viel wie Flüge, und trotzdem können Flughafenbetreiber Marmor verlegen, du aber nur schnöde Betonplatten.

Das wars mit dem Wort zum Montag.
Viele Grüße aus dem Zug nach München.
jan

 

Download des Vortrags als XPS oder PDF.

SharePoint 2010 Beta via MSDN und TechNet verfügbar

16.11.2009 19:54:06 | Thorsten Hans

Die Beta von SharePoint 2010 ist seit heute sowohl für MSDN als auch für TechNet Abonnenten verfügbar. Übermorgen werden alle Interessierten sich den neuen SharePoint downloaden können. Bis dahin haben die Großkunden :) einen kleinen Zeitvorsprung.

Bleibt zu hoffen dass die MSDN Downloads schnell genug sind um diesen Vorteil auch noch etwas nutzen zu können :)

 

Technorati-Tags:

Dieser Webpart kann nicht angezeigt werden

16.11.2009 16:01:20 | Andre Kraemer

"Dieser Webpart kann nicht angezeigt werden. Öffnen Sie diese Webseite in einem Windows SharePoint Services-kompatiblen HTML-Editor, wie beispielsweise Microsoft Office SharePoint Designer, um dieses Problem zu behandeln. Falls das Problem weiterhin besteht, wenden Sie sich an Ihren Webserveradministrator."

Dies ist mit großem Abstand meine Sharepoint Lieblingsfehlermeldung. Dahinter kann sich so ziemlich alles verbergen. Kürzlich erhielt ich diese Meldung, nachdem ich einige Änderungen an einem Dataview Webpart (DVWP) bei einem meiner Kunden vorgenommen hatte.

Typischerweise kommt diese Meldung, wenn man ein DVWP in einer Sharepoint Umgebung exportiert und in eine andere Importiert. Ursache ist in solchen Fällen die fehlerhafte Liste GUID, die innerhalb der XSL Transformation sowie als Parameter in den Webpart Eigenschaften gespeichert wurde.

In meinem Fall konnte ich diese Ursache allerdings ausschließen. Interessanterweise wurde der Fehler nämlich nur anonymen Nutzern der Seite angezeigt. Als angemeldeter Nutzer (mit Admin-Rechten) wurde der Webpart fehlerfrei angezeigt.

Nach einer Stunde relativer Ratlosigkeit und sprichwörtlicher Suche der Nadel im Heuhaufen fand ich glücklicherweise die Quelle des Fehlers.

Während der Entwicklung hatte ich die XSL Transformation des Wepart nicht direkt innerhalb des Webparts gespeichert. Stattdessen hatte ich sie in die Style Library ausgelagert. Was ich allerdings vergessen hatte: Die XSL Datei war zwar wunderbar ausgelagert, jedoch nicht veröffentlicht. Somit hatte ich als authentifizierter Benutzer zwar keine Probleme den Webpart anzuzeigen, anonyme Anwender konnten das Herzstück des Webparts - nämlich die Transformation - jedoch nicht zugreifen und erhielten somit (zurecht) die oben genannte Fehlermeldung.



blog.codemurai.de © André Krämer |Impressum | Abonieren

European Software Conference - Seamless integration in Windows 7

16.11.2009 12:03:00 | Peter Kirchner

Am Wochenende vom 7. und 8. November fand zum neunten Mal die European Software Conference in Berlin statt und versammelte Softwarehersteller aus ganz Europa und auch darüber hinaus für zwei Tage im Kempinski unter einem Dach.

Ich hatte Gelegenheit am Sonntag wieder zum Thema Windows 7 sprechen zu dürfen, was Softwarehersteller bei der Migration beachten müssen und welche neue Möglichkeiten sie hier haben. Die Folien dazu finden Sie hier:

Download des Windows 7 Vortrags / Download of the Windows 7 presentation

Office 2010 Beta steht zum Download im MSDN bereit!

16.11.2009 11:10:00 | Lars Keller

Seit heute steht die Office 2010 Beta (Build 14.0.4536.1000) im MSDN und Technet zum Download bereit. Yeah! Endlich ausprobieren was VSTO 4.0 kann! :-)

…95% Download fertig!

17.11.2009 - Treffen der .NET Developer Group Braunschweig – Antme! Challenge

16.11.2009 04:45:00 | Lars Keller

Nach dem Tom Wendel einer der Erfinder von Antme! bei uns war, wollen wir noch mal eine Antme! Challenge abhalten.
Bei der letzten Challenge hatte Team Hannover gewonnen. Werden Sie dieses Mal ebenfalls gewinnen? Jeder ist herzlich eingeladen mitzumachen. Alles was benötigt wird ist ein Laptop und Antme! (wir werden ausreichend Versionen zur Verfügung stellen). Selbst wenn du keinen Laptop hast, kannst du gern mitmachen. Es werden Teams gebildet.

Natürlich wird es auch etwas zu gewinnen geben! :-)

Weitere Informationen unter www.dotnet-braunschweig.de.

Wie immer ist jeder herzlich willkommen!

dotnet-kicks.de Button mit JavaScript einbinden

15.11.2009 20:36:00 | dotnet-kicks.de Blog

Mittlerweile wurden auf verschieden Blogs einige Möglichkeiten veröffentlicht, wie der dotnet-kicks.de Button in verschiede Blogsysteme integriert werden kann.
Was bisher noch fehlte war eine universelle JavaScript Lösung. Da der HTML Code für den Button nicht auf dem Server generiert wird, reicht es aus, wenn man das folgende JavaScript Snippet in das jeweilige Blogtemplate kopiert:


<div id="dnkContainer">
</div>

<script type="text/javascript">
 var insertLocation = document.getElementById('dnkContainer');
 var encodedTitle = encodeURI(document.title).replace('#', '%23');
 if (insertLocation) {
  var currentPageUrl = document.location.protocol + "//" + document.location.host + document.location.pathname + "&title=" + encodedTitle;
  var dotnetkicksLink = document.createElement('a');
  dotnetkicksLink.href = 'http://dotnet-kicks.de/kick/?url=' + currentPageUrl;
  var dotnetkicksImg = document.createElement('IMG');
  dotnetkicksImg.src = 'http://dotnet-kicks.de/Services/Images/KickItImageGenerator.ashx?url=' + currentPageUrl;
  dotnetkicksImg.border = 0;
  dotnetkicksLink.appendChild(dotnetkicksImg);
  insertLocation.appendChild(dotnetkicksLink);
 }          
</script>


Diese Lösung eignet sich unter anderem gut für Community Server Blogs. Im Blog von Lars Schmitt kann man es in Action sehen.
Den Snippet habe ich im Blog von Jon Galloway gefunden und auf dotnet-kicks.de angepasst. Außerdem wird bei dieser Version auch der Titel beim kicken zu dotnet-kicks.de übertragen.

Viel Spaß damit,
Jan

Dritter Snippet Wettbewerb auf dotnet-snippets.de

14.11.2009 13:36:32 | Jan Welker

In den letzten zwei Jahren gab es jeweils im Herbst einen großen Snippet Wettbewerb auf dotnet-snippts.de. Die Wettbewerbe lockten mit super Preisen, wie zum Beispiel einem Windows Vista oder einem Visual Studio 2008.

Auch in diesem Herbst habe ich wieder einen Wettbewerb vorbereitet. Dieses Mal gibt es als Hauptpreis ein Windows 7 Ultimate.
Weitere Preise sind: ein Office 2007 Standard, 4 Lizenzen für den tangible T4 Editor, eine Microsoft Arc Mouse sowie Bücher und Mousepads.

Ich bin mir sicher, dass bei dieser Aktion wieder viele wertvolle Snippets zusammen kommen, die dann hinterher von der ganzen Community genutzt werden können.

Der Wettbewerb beginnt am 15.11.2009 und endet am 13.Dezember 2009.

Alles weitere gibt es unter diesem Link:
http://dotnet-snippets.de/dns/dritter-snippet-wettbewerb.aspx

Viel Spaß beim mitmachen und weitersagen ;-)

Short Overview of SharePoint Features in Visual Studio 2010

14.11.2009 09:13:00 | Ozgur Aytekin

As you probably know, Visual Studio 2010 was announced last week and it contains a lot of great features and project templates for SharePoint developers. Below is a short overview for some of the SharePoint development related features and project templates.

  • Configurable deployment
  • Sandboxed and farm solutions
  • Extending SharePoint Tools
  • Feature and Package Designer
  • SharePoint Explorer
  • SharePoint Project and Project Item Templates
  • Project Templates
  • Project Item Templates
  • How to download, install and get started


http://blogs.msdn.com/sharepoint/archive/2009/10/28/short-overview-of-sharepoint-features-in-visual-studio-2010.aspx#9921742

Fehler verstecken leicht gemacht

13.11.2009 14:52:00 | Peter Bucher

Mit Try / Catch / Finally können in .NET Fehler behandelt werden.
Eigentlich eine gute Sache, allerdings sollte man aufpassen wo und wie man Fehler behandelt.

Vielerorts kann gelesen werden, dass das Fangen einer Allgemeinen Exception nicht gut sei, aber wieso ist das so?

Da ich es auch schon selber praktisch mehrmals erlebt habe, was das für schlimme Auswirkungen haben kann, ist es für mich nicht so schwer, diese Frage zu beantworten.

Ich möchte dies anhand eines kleinen, nachvollziehbaren Beispiels erläutern.

Gegeben ist folgender Code:


protected void Page_Load(object sender, EventArgs e)
{
    try
    {
        this.GridView1.DataSource = <DataSource>;
        this.GridView1.RowDataBound += GridView1_RowDataBound;
        CommandField deleteField = new CommandField
                   {
                     ShowDeleteButton = !this._recordsAreReadOnly,
                     DeleteText = “Löschen”,
                     DeleteImageUrl = "delete.png",
                     ButtonType = ButtonType.Image
                   };

         GridView1.Columns.Add(deleteField);
        // zusätzlichen Code…
        this.GridView.DataBind();
    }
    catch(Exception ex)
    {
        this.Logger.Log(ex);
    }
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if(e.Row.RowType == DataControlRowType.DataRow)
    {
        // zusätzlicher Code…
        ImageButton deleteButton = e.Row.FindControlRecursive<ImageButton>(c => c.CommandName == “Delete”);
        deleteButton.CssClass = “button_delete”;
        // zusätzlicher Code…
    }
}

Dieser Code, läuft - wie er jetzt da steht - ohne Probleme, solange die Daten nie als readonly gekennzeichnet werden.
Wird jetzt allerdings der Code erweitert, gibt es ein höchst merkwürdiges Verhalten, das ich mir zuerst überhaupt nicht erkären konnte.

Folgende Änderung:


ShowDeleteButton = !this._recordsAreReadOnly,

wird zu:


ShowDeleteButton = !this._recordsAreReadOnly && <Sicherheitsabfrage ob gelöscht werden darf>,

Der erste Teil der Bedingung liefert mit der Negation schlussendlich true und die Sicherheitsabfrage false, was ausgewertet dann einem false entspricht.
Somit werden die Löschen-Buttons nicht dargestellt. Gut. Eigentlich genau das was ich wollte.

Jedoch – und jetzt kommt der Haken – wird jetzt nur noch ein Datensatz im GridView angezeigt, anstelle von den zwei die in der Datenquelle vorhanden sind.

Im ersten Moment kam mir das ziemlich merkwürdig vor, da ich auch nirgendwo nochmals auf die Bedingung zugreifen und vor allem, weil auch kein Fehler geworfen wurde.

Kurz nachdem ich den Debugger angeworfen und kurz in den EventHandler “GridView1_RowDataBound” reingeschaut habe, kam es mir in den Sinn:

Böses Try / Catch, ein Fehler wurde versteckt, ohne das ich es gemerkt habe.

Was ist denn genau passiert?

Nun, da über die komplette Page_Load-Methode ein Try / Catch Konstrukt gespannt ist, das generell alle Fehler abfängt (Nicht behandelt, sondern eben “verschluckt”), bekomme ich den Fehler nicht zu Gesicht und der Code läuft in einem inkonsistenten Zustand weiter.

Der Eventhandler wird angemeldet und ein GridView1.DataBind()-Aufruf läuft im Eventhandler selber, also auch im Scope von besagtem Try / Catch, sodass die NullReferenceException, die eigentlich geworfen werden sollte, verschluckt wird.

Das hat dann dazu geführt, dass das GridView “irgendwie” noch halb fertig gerendert wird und man nichts vom Fehler mitbekommt, sondern eben nur einen Datensatz halb fertig gerendert wird.

Ich hoffe das dieses Beispiel ein wenig Klarheit bringt und vor allem euch aufweckt, Exception Handling mit Bedacht einzusetzen und nicht an einem solch komischen Verhalten zu verzweifeln.

Zusatz / Fazit:
Wie man sehen kann, ist der Scope (Wirkungsbereich) von Try / Catch um die ganze Page_Load-Methode gelegt.
Dies kann Sinn machen, jedoch nicht in der Mehrzahl der Fälle, wie auch in diesem Fall.

Meiner Meinung nach, und so steht es auch in den meisten Büchern, sollten Fehler punktuell abgefangen werden, nur dort wo man ihn auch behandeln kann und der Scope sollte möglichst klein gehalten werden, damit das Problem auch schnell identifiziert ist.

Die unbehandelten Fehler kann man dann generell in ASP.NET bspw. in der Global.asax.cs in der Methode Application_Error() loggen.
Ich persönlich gehe sogar so vor, das ich zuerst ohne Fehlerbehandlung entwickle und diese erst später hinzufüge.
So gehen während der Entwicklung keine Fehler vergessen und das Programm befindet sich nie in einem inkonsistenten Zustand.

Solchen Code wie oben gezeigt ist - wie auch Gregor im Kommentar bemerkt hat - vielerorts zu finden, was ich tragisch finde.
Die Konsequenzen daraus müssen in keinem Fall so harmlos sein, wie in diesem Beispiel gezeigt. Man stelle sich nur mal ein Atomkraftwerk vor, das durch eine inkonsistente Software gesteuert wird.

Bearbeitung / Korrekturen:
13.11.09 - Fehlendes Komma in den Codesnippets hinzugefügt
13.11.09 - Zusatz / Fazit hinzugefügt

Tutorial - Building the Contoso Auto Sales Office Business Application

13.11.2009 12:13:00 | Lars Keller

Mein MVP Kollege Robert Green hat ein interessantes Tutorial zur Outlook Add-In Entwicklung veröffentlicht. In dem Beispiel wird eine eigene Terminverwaltung implementiert.

Building the Contoso Auto Sales Office Business Application Part 1 - Scheduling Customer Appointments

Lesenswert! :-)

SharePoint 2010 Entwickler Trainings auf Channel 9

13.11.2009 12:10:00 | Thorsten Hans

clip_image002_3

Wie Paul Stubbs in seinem Post schreibt, sind auf Channel 9 sind ab sofort Entwickler Trainings verfügbar. Zu vielen wichtigen und neuen Themen in SharePoint 2010 sind Video Trainings bereitgestellt.

  • Getting Started with SharePoint 2010
  • SharePoint 2010 Developer Roadmap
  • Visual Studio 2010 Tools for SharePoint 2010
  • UI enhancements
  • Lists and Schemas
  • Linq 2 SharePoint
  • SharePoint 2010 Client OM
  • SharePoint 2010 Workflows
  • SharePoint 2010 Service Architecture
  • External Data
  • Enterprise Content Management
  • Search
  • PerformancePoint Services
  • Sandboxed Solutions
  • SharePoint 2010 Security (Claims based Security WIF)

Die in der Community bekannten Ted Pattison und Andrew Connell halten diese Video Trainings.

Eine weitere Übersicht aller verfügbaren Trainings auf Channel 9 findet Ihr auf dieser Übersichtsseite

image_3

Abbildung 1: Übersichtsseite aller Trainings auf Channel 9

 

DotNetKicks-DE Image

Missing header, footer and page number templates in Office 2007

13.11.2009 10:53:57 | Andre Loker

Office 2007 seems to get confused if you install a language version different from the language Windows uses. I recently installed an English version of Windows 7 after having used a German version of Vista for two years. When I installed Office 2007 (German) on Windows 7 I realized that several gallery items in Word were missing:

noheader nopagenumber

I reinstalled Office without success. On the web I found some forum threads (e.g. here) describing the same issue but the most common solution was to delete a file called Building Blocks.dotx in %appdata%\Microsoft\Document Building Blocks\<some language id>. “some language id” is 1031 (German) in my case. However, deleting the file did not fix the issue. As predicted the file got recreated when Word was started, but the gallery items were still gone.

Out of the blue I guessed that maybe there was an issue with me using an English Windows and a German Office. So I copied the Building Blocks.dotx from the 1031 subfolder to a new folder named 1033 (which is the language code for English). And what can I say – it worked again!

fixissue

workingheader

Conditional Constructing mit StructureMap

13.11.2009 09:04:00 | Jan Christian Selke

Diesmal schreibe ich über ein etwas anderes Thema. Conditional Constructing mit StructureMap. Ich bin zur Zeit sehr an der kontextabhängigen Codeausführung zur Entkopplung von Funktionsbausteinen interessiert. Vor kurzem hat sich dann auch eine praktische Möglichkeit dafür geboten.
Ein konkretes Beispiel, ist das Exception Handling in einer ASP.Net Anwendung.  Die Logik des ExceptionHandlings habe ich in ein Http Modul ausgelagert. Anhand des Typs der in der Anwendung aufgetreten Exception wird entschieden, welcher von verschiedenen Handlern instanziiert werden soll, um die Exception abhängig vom Typ zu behandeln. Wer hat dazu nicht schon einen Factory Code gesehen, der in etwa diesem glich:
public static IExceptionHandler CreateFor(Exception exception)
{
    if(exception is HttpException)
    {
        return new HttpExceptionHandler(exception);
    }

    if(exception is MyException)
    {
        return new MyExceptionHandler(exception);
    }

    return new GeneralExceptionHandler(exception);
}

Was aber, wenn nun die Abhängigkeiten herausgelöst werden sollen, so dass der Kontext die konkrete Logik bestimmt? Dies kann mit dem Einsatz eines Dependency Injection Frameworks realisiert werden. Ich habe mich für den Einsatz von StructureMap von Jeremy D. Miller entschieden. Vor allem auch deshalb, da StructureMap ein komfortable Möglichkeit der In-Code Konfiguration über die Registry Dsl bietet.
Der erste Schritt bestand für mich darin, ein Http Modul zu schreiben, dass sich auf das Error Event der Anwendung registriert. Dazu habe ich eine Klasse ExceptionHandlerModule geschrieben, die die Schnittstelle IHttpModule implementiert. In der Init Methode registriert sich das Modul dann auf das Event. Bei Auslösen des Events wird ein neuer IExceptionHandler durch den Aufruf ExceptionHandlerFactory.CreateFor erstellt, der in der jeweiligen Implementierung der Methode HandleException, die konkrete Exception behandeln kann.
public class ExceptionHandlerModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.Error += OnError;
    }

    private void OnError(object sender, EventArgs e)
    {
        IExceptionHandler handler
            = ExceptionHandlerFactory.CreateFor(HttpContext.Current.Error);
        handler.HandleException();
    }

    public void Dispose()
    {
    }
}

Die Registrierung des Http Moduls in der web.config erfolgt über den folgenden Eintrag.
webconfig
Weitere Beschreibungen zu Http Modulen kann man beispielsweise in der c-sharpcorner.com oder bei Microsoft googlen. Der Artikel bei Microsoft ist zwar schon älter, das Vorgehen ist aber unverändert.
Das grundlegende Element für die weitere Exception Behandlung ist eine einfache Schnittstelle IExceptionHandler mit nur einer Methode HandleException. Hierdurch erreichen wir einen höheren Grad an Entkopplung. Über einen Kontrakt wird aus der modularen Gestalt eines Handlers, der vielleicht nur von einer (abstrakten) Basisklasse abgeleitet wird, eine Komponente, die über DI injiziert werden kann.
public interface IExceptionHandler
{
    void HandleException();
}

Beispielhafte Implementierungen konkreter Handler könnten diesen entsprechen
public class MyExceptionHandler : IExceptionHandler
{
    public MyExceptionHandler(Exception exception)
    {   
    }

    public void HandleException()
    {
        // Do the handling magic…
    }
}

public class HttpExceptionHandler : IExceptionHandler { … }
public class GeneralExceptionHandler : IExceptionHandler { … }

Die Registrierung der ExceptionHandler in StructureMap erfolgt durch ableiten der Klasse Registry. Hierzu wird eine neue Klasse geschrieben, die von Registry aus dem namespace StructureMap.Configuration.DSL erbt. Die Mappings werden dann einfach in dem Konstruktor vorgenommen, es müssen keinen Methoden überschrieben werden oder etwas anderes dergleichen.
public class HandlerRegistry : Registry
{
    public HandlerRegistry()
    {
        ForRequestedType<IExceptionHandler>().TheDefault.Is.Conditional(
            x =>
            {
                x.If(y => HttpContext.Current.Error is HttpException).ThenIt.Is.OfConcreteType<HttpExceptionHandler>();
                x.If(y => HttpContext.Current.Error is MyException).ThenIt.Is.OfConcreteType<MyExceptionHandler>();
                x.TheDefault.Is.OfConcreteType<GeneralExceptionHandler>();
            });
    }
}

Das Initialisieren der ObjectFactory mit der eigenen HandlerRegistry erfolgt in der Regel in einer Bootstrapper Klasse. Bei dem Aufruf handelt sich um einen Einzeiler.
ObjectFactory.Initialize(x => x.AddRegistry(new HandlerRegistry()));
Nun kann auch endlich die Factory verschönert werden. Die if-elseif… oder switch Blöcke können durch nur noch einen Aufruf ersetzt werden.
Die nun deutlich übersichtlichere, von der statisch hinterlegten Abhängigkeit befreite Factory sieht nun also so aus.
public static class ExceptionHandlerFactory
{
    public static IExceptionHandler CreateFor(Exception exception)
    {
        return ObjectFactory.With(exception).GetInstance<IExceptionHandler>();
    }
}

Dem ganzen Entkoppeln ist jetzt natürlich noch kein Ende gesetzt. Dieses Spiel kann man beliebig weiter treiben. Beispielsweise kann die ExceptionHandlerFactory in dem HttpModul um einen Kontrakt erweitert werden. So kann die konkrete Factory aus dem Modul heraus gelöst werden. Wie weit dies in letzter Instanz getrieben wird, ist jedem selbst überlassen. Apropos getrieben – Was in diesem Beispiel viel zu kurz kam, ist der TDD Ansatz. Für die Entwicklung gilt natürlich “test first”.

Google PowerMeter – Mein S0-Stromzähler liefert erste Daten

12.11.2009 13:48:00 | Michael Schwarz

Seit ein paar Tagen arbeite ich an einem IEC 61850 Server für Schulungszwecke. Um nicht nur simulierte Messwerte zu liefern, habe ich mich für einen einfachen S0-Stromzähler entschieden. Die Impulse (zwischen 1.000 und 2.000 Impulse je kWh) der S0-Schnittstelle werden aufgezeichnet und können dann über einen IEC 61850 fähigen Client abgefragt werden.

Google PowerMeter in iGoogle Während meiner Suche nach S0-Zählern bin ich auf Google PowerMeter gestoßen. Mit diesem Dienst kann man grafisch den Stromverbrauch sichtbar machen. Google möchte wohl weiter Tipps geben, wie man den Stromverbrauch senken kann. Auch kann man den Stromverbrauch jederzeit mit einem früheren Zeitraum vergleichen (z.B. dem letzten Jahr).

Schnell mal die Google PowerMeter APIs implementiert, und siehe da, meine erste Auswertung ist auf iGoogle zu sehen.

Google PowerMeter - mein eigener Zähler

Weiter speicher ich nun auch jeden einzelnen Messwert in einem eigenen SQL Server 2008 im Internet. Mittels Reporting Services sollte dann auch eine eigene Auswertung von überall in der Welt möglich sein, da bin ich aber noch am Basteln.


Auf der Tech·Ed Europe 2009 – Tag 3

12.11.2009 13:38:19 | Jan Schenk



tweetmeme_url = 'http://blogs.msdn.com/jansche/archive/2009/11/12/auf-der-tech-ed-europe-2009-tag-3.aspx'; tweetmeme_source = 'jansche';

Da ist er schon wieder, mein letzter Tag auf der TechEd Europe. Natürlich bin ich auch froh, wieder nach Hause zu Frau und Kind zu kommen, aber die TechEd Europe in Berlin war schon etwas ganz besonderes. Wen wundert es, ich habe ja auch die letzten zwei Wochen an fast nichts anderes gedacht, morgens nach dem Aufstehen war die TechEd in meinem Kopf, tagsüber habe ich vorbereitet, mich zwar immer wieder vom Daily Business ablenken lassen, aber die TechEd hatte immer die Priorität 1. Das ist jetzt rum, auch wenn “nach der TechEd” eigentlich fast schon wieder “vor der TechEd” ist. So wie das bei allen großen Konferenzen und Messen – ich sage nur CeBIT – ist.

Dem Vorbereitungsstress zum trotz: Die TechEd Europe war mein Highlight des Jahres.

Am meinem letzten Tag auf der TechEd wurde ich dann nochmal so richtig produktiv. Ich habe ein Interview mit Orlando Escalante, dem Rollenmodell aller ITPro-Evangelisten weltweit, aufgenommen:

image

Ausserdem hat mir Achim den ein oder anderen Take verpatzt. Tja, Fernsehen ist nicht jedermanns Sache! ;-)

image

Mehr davon in bewegten Bildern gibt es auf alle Fälle in der nächsten Ausgabe von msdn tv (Http://msdn-online.de/msdntv). Versprochen!

München hat mich nun erst mal wieder, alolerdings nur bis Sonntag, am Montag bin ich schon auf der nächsten Konferenz, der webtech in Karlsruhe, um über Silverlight WOW!-Effekte zu sprechen.
Vielleicht sehen wir uns dort!

Ansonsten noch eine gute Zeit auf der TechEd Europe 2009 in Berlin (Home of the Fallen Wall)!

Und hier noch ein paar Schmankerl aus Jan’s Fotokiste:

CIMG0860 CIMG0868

CIMG0887 CIMG0885

1. Die Decke in der Berliner Republik, wo wir am Sonntag Abend gegessen haben.
2. Jason Zander spricht über die Windows Azure Platform in der General Session.
3. Pierre Joye und ich in der Hotelbar des Hotel Berlin, Berlin. Gut gelaunt.
4. Die lustige Runde aus Pierre Joye, Isabel Gomez Miragaya, Katrien De Graeve, Dirk Primbs, Bernhard Frank und Frank Koch (im Uhrzeigersinn).

SharePoint 2010 Client Object Model

12.11.2009 07:57:00 | Thorsten Hans

Verteilte Anwendungen mit SharePoint 2010 können nun innerhalb kürzester Zeit dank dem neuen SharePoint 2010 Client Object Model (nachfolgend Client OM) erstellt werden. Das Client OM stellt Entwicklern sehr viele Funktionen bereit mit deren Hilfe komplexe, verteilte SharePoint 2010 Anwendungen erstellt werden können.

Aus technischer Sicht ist das Client OM ein Proxy der vor die eigentliche SharePoint Lib geschaltet wird und mit dem neuen Client-WebService von SharePoint 2010 kommuniziert. (siehe Abbildung 1)

SP2010ClientOM

Abbildung 1 – SharePoint 2010 Client OM Lifecycle

 

Alt bewehrtes (Klassennamen)

Das SharePoint Team hat beim Erstellen des Client OM penibel darauf geachtet, dass SharePoint Entwicklern der Umstieg auf das Client OM einfach fällt. Ein Indiz hierfür sind die Klassennamen die im Client OM zur Verfügung stehen

Server

.NET managed Client

Silverlight

JavaScript

Silverlight

JavaScript

ClientContext

ClientContext

SPSite

Site

Site

Site

SPWeb

Web

Web

Web

SPList

List

List

List

SPListItem

ListItem

ListItem

ListItem

SPField

Field

Field

Field

Wie man der Tabelle entnehmen kann, muss lediglich das “SP” Prefix weggelassen werden wenn man mit dem Client OM von SharePoint 2010 arbeitet.

 

Der ClientContext, das Zentrum

Unabhängig davon ob ein Silverlight, ein CLR oder ein JavaScript Client erstellt wird bildet die Klasse ClientContext das Zentrum der Entwicklung mit dem SharePoint 2010 Client OM. Alle Abfragen die zum SharePoint Server gehen werden über den ClientContext realisiert. Ein kleines Beispiel sollte das ganze verständlich darstellen

   1:  ClientContext ctx =
   2:       new ClientContext(“http://mySharePoint2010Server”);
   3:   
   4:  ctx.Load(ctx.Web);
   5:  ctx.Load(ctx.Web.Lists);
   6:   
   7:  var allVisibleListsQuery = from list in context.Web.Lists 
   8:                where list.Hidden = false 
   9:                select list;
  10:   
  11:  var results = 
  12:      context.LoadQuery(allVisibleListsQuery);

Wie man sieht läuft alles über den ClientContext, was die Sache sehr einfach macht, weil man nur wenige Typen benötigt um komplexe Anforderungen zu realisieren.

 

Fazit

Das neue SharePoint 2010 Client OM wird für viele SharePoint Entwickler eine nette und komfortreiche Sache werden. Hierdurch können schnell verteilte Anwendungen die auf SharePoint basieren entwickelt werden, ohne auf die veralteten asmx WebServices zugreifen zu müssen, wie es noch bei SharePoint 2007 der Fall ist.

 

 

DotNetKicks-DE Image

Eine neue Folge "msdn tv - Nachrichten für Entwickler"

11.11.2009 07:04:57 | Oliver Scheer

Für die aktuelle Folge von „msdn tv“ hatte Moderator Jan Helmhut Schenk Gelegenheit, mit Hannes Preishuber zu sprechen, dem Vorstand des IT-Weiterbildungsspezialisten ppedv AG (Burghausen). Natürlich geht’s dabei u.a. um die anstehende Entwicklerkonferenz VSOne, die im Februar 2010 in München stattfindet, aber auch ums Trainingsbusiness im allgemeinen, um Technikvorlieben und um Pro & Contra Open Source.
In den Kurzmeldungen: die Beta 2 von Visual Studio 2010 und .NET 4.0, der erste Geburtstag von Small Basic, Neues zur Microsoft Press Preview, die Online-Trainings der Weiterbildungsinitiative LiftOff und die integrierte Entwicklungsumgebung Eclipse zur Verbesserung der Interoperabilität von Windows 7, Windows Azure und Silverlight.

Ausserdem gibt es am Ende der msdn tv-Folge noch die Gewinnmöglichkeit für eine von 5 Expression Studio 3 Lizenzen. Einfach diesen Text twittern (@jansche RTen und Expression Studio gewinnen! msdn tv - Nachrichten für Entwickler http://msdn-online.de/msdntv #msdntv) um automatisch an der Verlosung teilzunehmen. Die Gewinnspielbedingungen findet ihr hier: http://www.der-evangelist.de/rechtliches/expression-studio-gewinnspiel-teilnahmebedingungen/

Die Gewinner werden schriftlich über eine DirectMessage (bei Teilnahme über twitter.com) oder per Post (bei Einsendung einer Postkarte, Absender nicht vergessen!) benachrichtigt.

Den ganzen Artikel findet ihr auf Jans Blog, weitere „msdn tv“-Folgen gibt es auf http://msdn-online.de/msdntv.

Launch Event: Windows Azure Launch Day am 26.11.2009 in Stuttgart auf der Cloud Conf

10.11.2009 23:30:46 | Robert Mühsig

Windows Azure ist demnächst auch für den produktiven Einsatz vollständig gerüstet. Microsoft stellt in Stuttgart auf der Cloud Conf am 26.11 erstmalig die “Version 1.0″ von Azure vor und zeigt wie man Azure & und Microsoft Online Services nutzen im kann. Mehr Informationen… Auf dem Windows Azure Platform Launch Day stellt Microsoft erstmalig die produktive [...]SHARETHIS.addEntry({ title: "Launch Event: Windows Azure Launch Day am 26.11.2009 in Stuttgart auf der Cloud Conf", url: "http://code-inside.de/blog/2009/11/10/launch-event-windows-azure-launch-day-am-26-11-2009-in-stuttgart-auf-der-cloud-conf/" });

Launch Event: Windows Azure Launch Day am 26.11.2009 in Stuttgart auf der Cloud Conf

10.11.2009 23:16:41 | Jan Welker

Auf dem Windows Azure Platform Launch Day stellt Microsoft erstmalig die produktive Version von Windows Azure in Deutschland vor. Entwickler, IT-Dienstleister, Software-Hersteller und Unternehmen lernen hier, wie man die Microsoft Online Services (Sharepoint, Exchange, Office Web Applications) und die Windows Azure Platform einsetzen kann und wie man für Windows Azure Platform Anwendungen entwickelt. Auf diesem exklusiven Premiereevent erfahrt Ihr alles Wichtige über die Cloud Angebote von Microsoft und wie Unternehmen davon profitieren können. Jeder Teilnehmer erhält auch das Microsoft-Press Buch „Cloud Computing mit der Windows Azure Platform“.

Anmeldung und weitere Infos findet Ihr unter: http://go.microsoft.com/?linkid=9695889

Bonn: Vortrag über “Dynamic Languages” aus erster Hand

10.11.2009 22:38:10 | Roland Weigelt

Sehr kurzfristig hat sich die Gelegenheit ergeben, Harry Pierson, Program Manager bei Microsoft im IronPython Team, für einen Vortrag nach Bonn zu holen – da sagt man natürlich nicht Nein, wenn man die Chance hat.

Am 17.11.2009 um 19:00 (Einlass ab 18:30) wird Harry über dynamische Sprachen im Microsoft .NET Umfeld sprechen:

As you may know, Microsoft is developing IronPython and IronRuby, .NET implementations of the popular open-source programming languages Python and Ruby. While it's clear that Microsoft wants to attract existing Python and Ruby developers to .NET, the role of IronPython and IronRuby for existing .NET developers is less clear. What value is there for a .NET developer in learning IronPython? What are the tradeoffs between IronRuby and a more traditional .NET language like Microsoft Visual C# or Visual Basic? Harry Pierson, new PM for IronPython, discusses where dynamic languages fit in the.NET developer's toolbox.

Veranstaltungsort sind die Räume der Comma Soft AG, nur wenige Minuten von der A59 Ausfahrt Pützchen entfernt (Anfahrtsbeschreibung). Dort finden auch regelmäßig die Treffen der Bonner .NET User Group “Bonn-to-Code.Net” statt, das nächste übrigens bereits eine Woche später.

MSDN stellt Security Development Lifecycle-Prozess fuer Agile Softwareentwicklung vor

10.11.2009 20:33:16 | Kay Giza

Die Microsoft Trustworthy Computing Group hat neue Richtlinien für den Security Development Lifecycle (SDL)-Prozess herausgegeben. Dies wurde gestern und heute ausführlich auf der TechEd Europe 2009 in Berlin bekannt gegeben. "SDL for Agile Development" ermöglicht noch mehr Entwicklern die Nutzung anerkannter Sicherheitspraktiken. Damit können sie Microsofts SDL-Prozess auch im Agilen Entwicklungsprozess direkt in ihre Softwareentwicklungsumgebungen integrieren, um die Sicherheit ihrer Anwendungen zu erhöhen... [... alle Details sowie Dowanload-Links finden Sie in diesem Blogeintrag auf Giza-Blog.de]

This post is powered by www.Giza-Blog.de | Giza-Blog.de: RSS Feed
Visit:  MSDN Online | Follow MSDN Online on Twitter | Follow Kay Giza on Twitter
Daily News on MSDN:  MSDN Aktuell
© Copyright 2006-2010 Kay Giza. All rights reserved. Legal
Subscribe

IronPython und IronRuby: Besuch aus Redmond in Bonn am 17.11.2009

10.11.2009 19:05:58 | Albert Weinert

Es ist mal wieder eine der einmaligen Gelegenheiten jemanden direkt aus der Productgroup aus Redmond live in Deutschland sprechen zu sehen und zu hören.

Harry Pierson, Program Manager bei Microsoft im IronPython Team in Redmond, wird einen Vortrag über dynamische Sprachen in .NET (IronPython und IronRuby) halten:

As you may know, Microsoft is developing IronPython and IronRuby, .NET implementations of the popular open-source programming languages Python and Ruby. While it's clear that Microsoft wants to attract existing Python and Ruby developers to .NET, the role of IronPython and IronRuby for existing .NET developers is less clear. What value is there for a .NET developer in learning IronPython? What are the tradeoffs between IronRuby and a more traditional .NET language like Microsoft Visual C# or Visual Basic? Harry Pierson, new PM for IronPython, discusses where dynamic languages fit in the.NET developer's toolbox.

Also nicht wie hin, kostest nichts.

Bitte melde Euch kurz mit einer E-Mail an mail@bonn-to-code.net an. So dass der andrang abgeschätzt werden kann.

17.11.2009 ab 19 Uhr bei Comma Soft in Bonn: http://www.bonn-to-code.net/1736.aspx

Auf der Tech·Ed Europe 2009 – Tag 2

10.11.2009 18:38:52 | Jan Schenk



tweetmeme_url = 'http://blogs.msdn.com/jansche/archive/2009/11/10/auf-der-tech-ed-europe-2009-tag-2.aspx'; tweetmeme_source = 'jansche';

image

“Ladies and Gentlemen, I‘d like to welcome you on board flight SVR202. Our Destination for todays flight is „Cloud-Knowledge“, a beautiful place where you have a drink or two while your resources scale up and down as they need to.
Our ETA is 10:15, during our flight you might want to follow the on board entertainment, which takes place on the stage and the screens in front of you.”

So habe ich heute meine Session “Windows Azure Flight Tour – Looking at the Clouds from Above” auf der TechEd Europe 2009 angefangen. Und ich war selbst erstaunt, als ich dafür Applaus bekommen habe. Ich wusste, dass es lustig wirken würde, vor allem, da eine der Hostessen, die die Sääle betreuen, sich bereit erklärt hatte als Stewardess “Boarding Completed” ins Mikro zu sagen. Worauf ich mit meinem Kapitäns-Opener anfangen konnte.

Offenbar war es unterhaltsam! An dieser Stelle würde ich mich noch gerne bedanken, und zwar bei meiner netten Assistentin, beim Technik-Team in den Säälen und bei allen Besuchern meiner Sessions und der TechEd. Ohne euch gäbe es keine TechEd!

teched_tlc_stitch2

Natürlich war ich heute auch wieder mit der Kamera unterwegs und habe nicht nur Fotos, sondern auch Videos gemacht. Die gibt es allerdings erst in der nächsten Folge von msdn tv!

Wie es übrigens aussieht, wenn sich TechEd-Besucher entspannen und ihren Köpfen und Füßen mal eine Pause gönnen, könnt ihr hier sehen:

_MG_9564

Allerdings muss ich dazu sagen, dass dieses Bild während der Mittagspause entstanden ist. Eine Runde Ausruhen ist keine Schande, eine Runde Guitar Hero auf der XBOX auch nicht!

Das wars für heute von der TechEd Europe 2009. Morgen darf ich auch nochmal hier sein, und nachmittags geht es ab nach Hause zu Frau und Kind. Das ist, wie immer, das härteste am Wegsein, dass ich die beiden nicht einfach mit nehmen kann.

Bis morgen bei Tag 3,
jan

Das Outlook-Fenster kann nicht geöffnet werden...

10.11.2009 15:21:00 | Martin Hey

Vor wenigen Tagen begrüßte mich Outlook mit der vielsagenden Meldung "Microsoft Office Outlook kann nicht gestartet werden. Das Outlook-Fenster kann nicht geöffnet werden."

Seltsam daran war, dass im Hintergrund dieser Meldung sehr wohl ein Outlook-Fenster zu sehen war, dieses aber nach einem Klick auf OK in obiger Meldung gleich wieder verschwand.

Einige Suche brachte zu Tage, dass das Profil neu erstellt werden muss oder XML-Dateien korrupt sind oder oder oder....

Aber alle diese Hinweise brachten mich zu keinem Erfolg. In einem letzten Aufbäumen der Kreativität versuchte ich dann noch die Reparatur-Kommandozeilenoptionen von Outlook selbst und siehe da - mit outlook.exe /resetnavpane hatte ich Erfolg und Outlook startet seitdem wieder normal.

Taskbar Meters – Anzeige von CPU/Speicherauslastung und Festplattenaktivität unter Windows 7

10.11.2009 09:19:00 | Michael Schwarz

Richtig coole Sache: Jeff Key nutzt die neuen Windows 7 Taskbar Features um CPU/Speicherauslastung als auch die Festplattenaktivität grafisch anzuzeigen.

image

Ich selber habe die Windows Gadgets unter Windows Vista nie gemocht, lag daran, dass sie mir immer wertvollen Platz auf dem Bildschirm (trotz 3 Monitoren) weggenommen haben. Hier in der Taskbar stören sie mich nicht.

Und das Beste: Jeff hat den Source Code veröffentlicht, für .NET Entwickler die Gelegenheit, sich die neuen Windows 7 Taskbar Features mal genauer anzuschauen.

Jeff hat übrigens noch weitere .NET Tools auf Lager.

kWh-Logger – Energiesparzähler

10.11.2009 08:32:00 | Michael Schwarz

Seit ein paar Wochen arbeite ich an einem Energiesparzähler Stromzähler, der meinen Energieverbrauch grafisch anzeigen, und verschiedene Auswertungen ermöglichen soll. Die meisten Stromzähler bieten eine S0-Schnittstelle (nicht zu verwechseln mit S0-Bus bei ISDN) an, die pro kWh zwischen 1000 und 2000 Impulse liefern. Diese kann man dann relativ einfach mitzählen, und so den aktuellen Stromverbrauch messen.

IMG_9729_2Dipl. Ing. Tostmann hat in Zusammenarbeit mit dem Energiezählershop von Johann Stark bereits ein solches Gerät entwickelt:

  • 4 x S0-interface after DIN 43 864
  • AT90USB1287 processor 8MHz @ 3.3V
  • native USB2.0 interface
  • MicroSD card slot
  • ENC28J60 Ethernet
  • 230V / 3Watt power supply (1.5W true power)
  • RTC with NVRAM
  • Switch // 6 LED
  • FPC-ISP connector (adapter needed)
  • fits into 3TE DIN rail case

Das Gerät ist wirklich einfach zu bedienen, ein einfacher http-Request reicht aus, um z.B. aus einer .NET Anwendung an die Daten im CSV Format zu kommen:

GET http://daten.kwh-logger.de/a.dat HTTP/1.1
2009-09-17 13:55:14, 1, 186
2009-09-19 14:03:55, 1, 187 2009-09-19 14:04:31, 1, 188 2009-09-19 14:05:10, 1, 189 2009-09-19 14:05:45, 1, 190 2009-09-19 14:06:05, 1, 191 2009-09-19 14:06:16, 1, 192 2009-09-19 14:06:28, 1, 193 2009-09-19 14:06:40, 1, 194 2009-09-19 14:07:06, 1, 195

Mehr Details und Bilder dazu auch unter busware.de.

Microsoft veröffentlich neues Facebook SDK 3.0

10.11.2009 08:07:00 | Michael Schwarz

Gestern hat Microsoft eine neue Version des Facebook SDKs zum Download bereitgestellt, inzwischen ist man bei Version 3.0 angekommen. Seit der Zusammenarbeit mit Facebook im Jahr 2007 versucht man damit die .NET Entwickler bei der Entwicklung von Facebook Anwendungen zu unterstützen.

Hier mal die wichtigsten Neuerungen direkt von den Microsoft Web Seiten:

    • Provide better doc and samples
    • Provide support for Silverlight
    • Provide support for ASP.NET MVC
    • Provide improved support for WPF
    • Provide improved support for FBML (FBML Server Controls)
    • Provide a login control that can be used to replace the BasePage and/or MasterPage for Canvas Development
    • Improve out of the box support for Extended Permission Prompts
    • Refactor core source to improve maintainability and design
    • Fix known bugs

Schade, dass man beim Upgrade von Version 2.0/2.1 auf die neue Version 3.0 wieder einige Methoden umbenannt hat:

As part of this, we worked closely with the Concept Development Team at Microsoft to help design the Silverlight and WPF support. Also, after discussions with Microsoft it was decided that the namespaces and methods should be updated again to be more consistent with traditional .NET APIs. This will cause some breaking changes to everyone as they move to 3.0. But, the main goal is that we wanted to get it right this time so that this could become an officially supported client library. Microsoft is working with Facebook to get the toolkit identified as the officially supported library. The plan is to provide real-time support and updates to keep the toolkit in synch with the Facebook API.

ASP.NET ListView und OnItemCreated

10.11.2009 08:05:33 | Daniel Schädler

In einem vorherigen Post habe ich gesagt dass ich dass OnItemCreated Ereignis des ListView's nicht mehr brauchen will. Dass kann ich zum Glück wiederrufen, denn dann wäre die OnItemDataBound Methode (Ereignis) ein wenig überladen. Ich gehe nun nach folgender Regel: 1. Wenn ich serverseitigen Code eines Controls dass im ListView vorhanden ist, ausführen will, dann behandle ich dieses im OnItemDataBound (dann ich auch das ListView gerendert und auch die Events zu jedem entsprechenden Control wurden in Verbindung mit der ListView (eindeutigen ID) generiert. 2. Wenn ich nur Daten abfüllen will (z. Bsp. habe ich ein GridView in einem Item) und möchte keine Server-seitigen Aktionen ausführen, dann kann ich das OnItemCreated Ereignis verwenden. Im aktuellen Fall habe ich das TabPanel des AjaxControlToolkits mit dem des JQueryUI's ausgewechselt. Zu diesem Zweck ist im ItemTemplate des ListViews folgendes Markup vorhanden.
   1: <ItemTemplate>
   2:     <ul>
   3:         <li><a id="RoomTbPanel_Hyperlink" runat="server"></a>
   4:         <asp:Label ID="RoombTabPanel_Label" runat="server" OnLoad="Label_OnLoad"></asp:Label>
   5:         </li>
   6:         <li><a id="Artice_TabPanel_Hyperlink" runat="server"></a>
   7:         <asp:Label ID="ArticleTabPanel_Label" runat="server" OnLoad="Label_OnLoad"></asp:Label>
   8:         </li>
   9:         <li><a id="Device_TabPanel_Hyperlink" runat="server"></a>
  10:         <asp:Label ID="DeviceTabPanel_label" runat="server" OnLoad="Label_OnLoad"></asp:Label>
  11:         </li>
  12:         <li><a id="Software_TabPanel_Hyperlink" runat="server"></a>
  13:         <asp:Label ID="SoftwareTabPanel_Label" runat="server" OnLoad="Label_OnLoad"></asp:Label>
  14:         </li>
  15:     </ul>                                    
  16:             <div id="RoomTabPanel" runat="server">    
  17:                                               <asp:GridView ID="DeviceStore_GridView" runat="server" HeaderStyle-CssClass="GridViewHeader" AutoGenerateColumns="true" />
  18:                                                </div>
  19:             <div id="DeviceTabPanel" runat="server">    
  20:                                                         <asp:GridView ID="CommercialOrderStepOverView_Device_Grid" runat="server" AutoGenerateColumns="true" />
  21:                                                         <asp:Label ID="Information_Label" runat="server" OnLoad="Label_OnLoad"></asp:Label>
  22:         </div> 
  23:             <div id="ArticleTabPanel" runat="server">    
  24:                                                         <asp:GridView ID="CommercialOrderStepOverView_Article_Grid" runat="server" AutoGenerateColumns="true" />
  25:         </div>
  26:             <div id="SoftwareTabPanel" runat="server">
  27:             <asp:GridView ID="CommercialOrderStepOverView_Software_Grid" runat="server" AutoGenerateColumns="true" />
  28:             </div> 
  29:         </div>
  30:                     </ItemTemplate>

Damit das ganze dann auch seinen TabPanel Charakter erhält, habe ich im entsprechenden Js der Seite foglenden JQuery Code hinzugefügt.

Damit’s dann auch ein Tab wird, muss das ul-Tag mit einem Div umspannt werden dass dann den TabPanel darstellt.

   1: <div id="TabContainer" runat="server">
   2: --> Hier kommt dann der relevante Code von obigem Codeschnippsel hinzu
   3: </div>
   1: $("div").each(function() {
   2:     if ($(this)[0].id.search("TabContainer") != -1) {
   3:         $(this).tabs();
   4:     }
   5: });

Sucht einfach alle Div’s in der Seite, geht diese durch und schaut dann ob es dem Namen entspricht (dass Div dass als TabPanel dargestellt werden soll). Danach können die Divs im OnItemCreated Ereignis verarbeitet werden.

   1: // Finding the divs that are representing the tabpanels
   2: HtmlGenericControl tabContainer = (HtmlGenericControl) e.Item.FindControl("TabContainer");
   3: HtmlGenericControl deviceTabPanel = (HtmlGenericControl) e.Item.FindControl("DeviceTabPanel");
   4: HtmlGenericControl roomTabPanel = (HtmlGenericControl)e.Item.FindControl("RoomTabPanel");
   5: HtmlGenericControl articleTabPanel = (HtmlGenericControl)e.Item.FindControl("ArticleTabPanel");
   6: HtmlGenericControl softwareTabPanel = (HtmlGenericControl)e.Item.FindControl("SoftwareTabPanel");
   7:  
   8: HtmlAnchor roomTbPanelHyperlink = (HtmlAnchor) e.Item.FindControl("RoomTbPanel_Hyperlink");
   9: HtmlAnchor articeTabPanelHyperlink = (HtmlAnchor)e.Item.FindControl("Artice_TabPanel_Hyperlink");
  10: HtmlAnchor deviceTabPanelHyperlink = (HtmlAnchor)e.Item.FindControl("Device_TabPanel_Hyperlink");
  11: HtmlAnchor softwareTabPanelHyperlink = (HtmlAnchor)e.Item.FindControl("Software_TabPanel_Hyperlink");
  12:  
  13: // Assigning the correct navigation targets to the hyperlinks
  14: roomTbPanelHyperlink.HRef = string.Format(@"#{0}", roomTabPanel.ClientID);
  15: articeTabPanelHyperlink.HRef = string.Format(@"#{0}", articleTabPanel.ClientID);
  16: deviceTabPanelHyperlink.HRef = string.Format(@"#{0}", deviceTabPanel.ClientID);
  17: softwareTabPanelHyperlink.HRef = string.Format(@"#{0}", softwareTabPanel.ClientID);
  18:  
  19: // Assigning the translation values to the hyperlinks as title
  20: roomTbPanelHyperlink.Title = EnumUtils.Translate(typeof(RoomType), RoomType.DeviceStore).Translation;
  21: articeTabPanelHyperlink.Title = ResourceManager.GetMessage(typeof (Article), "text");
  22: deviceTabPanelHyperlink.Title = ResourceManager.GetCustomMessage(typeof(Device), "Device_Plural_text");
  23: softwareTabPanelHyperlink.Title = ResourceManager.GetMessage(typeof(SoftwareProduct), "text");
  24:  
  25: // Setting visibility of each tabpanel
  26: roomTabPanel.Visible = this._presenter.StoresAndDevices != null && this._presenter.StoresAndDevices.Count > 0 ? true : false;
  27: articleTabPanel.Visible = this._presenter.Articles != null && this._presenter.Articles.Count > 0 ? true : false;
  28: deviceTabPanel.Visible = this._presenter.Devices != null && this._presenter.Devices.Count > 0 ? true : false;
  29: softwareTabPanel.Visible = this._presenter.SoftwareProducts != null && this._presenter.SoftwareProducts.Count > 0 ? true : false;

Die Verlinkung mit den einzelnen Elementen wie (Href auf das richtige Div) wird im OnItemCreated gemacht, da dort die eindeutigen ID’s der Div’s (da diese das runat=”server” aufweisen) bereits gerendert worden sind.

Die Präprozessor Direktive #line

09.11.2009 21:40:00 | Lars Schmitt

Präprozessordirektiven wie zb

  • #region
  • #endregion
  • #if
  • #else
  • #endif
  • #warning

sollten mittlerweile die meisten Entwickler kennen, jedoch was ist zb mit der #line - Direktive.

Durch den Präprozessor Befehl #line hidden, werden aufeinander folgende, bis zur #line default Direktive, Quellcode Zeilen, vor dem Debugger verborgen.

Was bringt mir als Entwickler diese Direktive?

Der Vorteil für den Entwickler liegt darin, dass er beim Debuggen nicht immer wieder in Methoden wie zB. die überschrieben Methode WndProc eines Forms reinsteppt. (Welchem Entwickler, hat es noch nicht den letzten Nerv geraubt, wenn er beim Debuggen, immer wieder in diese Methode zu reinsteppt)

#line hidden protected 

override void WndProc(ref Message m){

      …

      base.WndProc(ref m);}

#line default

Der Vollständigkeits halber, noch einen weiterer Anwendungsfall, der der #line Direktive.

In diesem Beispiel zeuge ich, wie man mittels der #line Direktive, die Code Zeile und den Dateinamen in Fehler oder Warnungs Ausgaben manipulieren kann.

Falls ihr eine sinnvolle Verwendung findet, immer her damit, denn leider fällt es mir schwer, für diesen Präprozessor, eine wirklich sinnvolle Verwendung zu finden.

using System;   

using System.Collections.Generic;   

using System.Linq;   

using System.Text;   

namespace ConsoleApplication2   

{   

    class Program   

    {   

        static void Main(string[] args)   

        {   

            int zahl = 0;   

//#line Zeilennummer “Filename”  der Filename ist optional   

#line 42 "Die Antwort aller Fragen, befindet sich in der QuellcodeZeile.cs"   

            int neueZahl = 23 / zahl;   

#line default   

            Console.WriteLine();   

        }   

    }   

}

und an dieser Stelle, der dazugehörige Fehler:

at ConsoleApplication2.Program.Main(String[] args) in c:\Users\Lars\Documents\Visual Studio 2010\Projects\ConsoleApplication2\ConsoleApplication2\Die Antwort aller Fragen, befindet sich in der QuellcodeZeile.cs:line 42

...

Benutzerdefinierte Animationen in Silverlight

09.11.2009 21:18:00 | Stefan Lange

Bei einer Silverlight Applikation ergab sich kürzlich die Aufgabe, einen bestimmten Bereich über eine Art „Maximize Button“ so zu vergrößern, dass er sich über den ganzen im Browser zur Verfügung stehenden Platz erstreckt. Hier zunächst ein Beispiel, wie es funktionieren soll:

Beispiel ohne Animation

Die äußeren Bereiche sind hier im Beispiel nicht ganz auf 0 verkleinert, um den Effekt deutlicher zu machen. Die Implementierung ist einfach: Die Row- und ColumnDefinition Objekte werden per Code einfach mit neuen GridLength Objekten umkonfiguriert, so dass der Content Bereich den gesamten verfügbaren Platz einnimmt.

void Maximize()
{
  const int zero = 15;  // set to non-zero for demonstration purposes only

  LayoutRoot.ColumnDefinitions[0].Width = new GridLength(zero, GridUnitType.Pixel);
  LayoutRoot.ColumnDefinitions[1].Width = new GridLength(1, GridUnitType.Star);
  LayoutRoot.ColumnDefinitions[2].Width = new GridLength(zero, GridUnitType.Pixel);

  InnerLayout.RowDefinitions[0].Height = new GridLength(zero, GridUnitType.Pixel);
  InnerLayout.RowDefinitions[1].Height = new GridLength(1, GridUnitType.Star);
  InnerLayout.RowDefinitions[2].Height = new GridLength(zero, GridUnitType.Pixel);
  InnerLayout.ColumnDefinitions[0].Width = new GridLength(zero, GridUnitType.Pixel);
  InnerLayout.ColumnDefinitions[1].Width = new GridLength(1, GridUnitType.Star);
}

void Restore()
{
  LayoutRoot.ColumnDefinitions[0].Width = new GridLength(1, GridUnitType.Star);
  LayoutRoot.ColumnDefinitions[1].Width = new GridLength(700, GridUnitType.Pixel);
  LayoutRoot.ColumnDefinitions[2].Width = new GridLength(1, GridUnitType.Star);

  InnerLayout.RowDefinitions[0].Height = new GridLength(100, GridUnitType.Pixel);
  InnerLayout.RowDefinitions[1].Height = new GridLength(1, GridUnitType.Star);
  InnerLayout.RowDefinitions[2].Height = new GridLength(30, GridUnitType.Pixel);
  InnerLayout.ColumnDefinitions[0].Width = new GridLength(180, GridUnitType.Pixel);
  InnerLayout.ColumnDefinitions[1].Width = new GridLength(1, GridUnitType.Star);
}

Für den Anwender sieht das Umschalten aber nicht besonders attraktiv aus. Der zu vergrößernde Bereich sollte sich beim Maximieren nicht schlagartig ausdehnen, sondern animiert anwachsen. Entsprechendes gilt natürlich auch für ein späteres Restore in die Ursprungsgröße.

Die Aufgabe ist nun nicht ganz so einfach, da eine Animation von Row/ColumDefinition weder in Silverlight noch in WPF vorgesehen ist. Das zu animierende Objekt ist der Value Type GridLengh, für den es keine im Framework vorhandene Animation gibt. In WPF könnte man nun eigene Animation GridLengthAnimation implementieren, die man von AnimationTimeline ableitet. Wie das geht wurde schon sehr oft erklärt.

In Silverlight ist die Ableitung eigener Animationen weder vorgesehen noch möglich. Von der abstrakten Klasse Timeline sind 7 fest definierte Animationen sowie die Klasse Storyboard abgeleitet; alle Ableitungen sind sealed. Diese vordefinieren Animationen sind in Silverlight lediglich Wrapperklassen. Die eigentliche Arbeit wird von der darunterliegenden Silverlight Runtime ausgeführt, was mit ziemlicher Sicherheit aus Performance Gründen so gemacht wurde. Leitet man probeweise eine eigene Klasse von Animation ab und fügt sie in einen Storyboard ein, erhält man sofort eine COM Runtime Exception. So einfach geht es also nicht.

Alternativen

Zunächst einmal sollte man sich natürlich fragen, ob es für ein gegebenes Problem wirklich notwendig ist eine eigene Animation zu implementieren. Bei meinem konkreten Maximize/Restore Problem könnte ich ja auch anders vorgehen: Anstatt die Breiten und Höhen von Zeilen und Spalten verschiedener Grids zu animieren, wäre es auch möglich, überall den GridUnitType auf Auto zu setzen und in die entsprechenden Grid Zellen Border Objekte packen. Border Objekte besitzen die von FrameworkElement geerbten Properties Width und Height, die ganz normal mittels DoubleAnimation animiert werden können. Da die Zeilen und Spalten der Grid Objekte auf Auto stehen und sich der Größe der darin liegenden Border Objekte anpassen, führt eine Animation der Border Objekte letztlich zu einer Animation des Gesamtlayouts. Der große Nachteil dabei ist aber, dass man dann das gesamte Layout selber berechnen muss, denn so etwas Praktisches wie GridUnitType.Star stünde einem dann nicht zur Verfügung. Also scheint es doch sinnvoll zu sein, ein wenig über die Animation von GridLength Objekten nachzudenken.

Lösungsansatz in Silverlight

Glücklicherweise konnte ich mich an einen Artikel von Charles Petzold erinnern, in dem er eines seiner Beispiele aus seinem WPF Buch auf Silverlight ans Laufen gebracht hat. Er demonstriert darin, wie man die WPF Animation MatrixAnimationUsingPath unter Silverlight nachbaut (siehe hier).

Meine Klasse MaximizeRestoreAnimation funktioniert nach dieser Vorlage. Die Grundidee besteht darin, sich in das Rendering Event der Klasse CompositionTarget einzuklinken. Dieser Event wird vor dem Rendern jedes einzelnen Frames aufgerufen und dient zur Berechnung des nächsten Animationsschrittes. Hier ein Quellcodeauszug:

void OnCompositionTargetRendering(object sender, EventArgs e)
{
  // Comes here for every rendered frame, so don't waste performance if nothing is to animate
  if (!(_startAnimation || _running))
    return;

  // Prevent division by zero
  if (!Duration.HasTimeSpan)
    return;

  // Calculate progress using the storyboard Ticks
  double progress = (double)Storyboard.GetCurrentTime().Ticks / Duration.TimeSpan.Ticks;

  if (_startAnimation)
  {
    // switch to running
    _startAnimation = false;
    _running = true;
  }

  if (_maximized)
    AnimateMaximize(progress);
  else
    AnimateRestore(progress);
}

Mit Hilfe eines Storyboards wird der Fortschritt der Animation als eine Zahl zwischen 0 und 1 berechnet. Diese Zahl dient dann zum Skalieren der Breiten und Höhen der Grid Rows/Columns. Petzolds Trick besteht darin, so viel wie möglich von der vorhandenen Silverlight Infrastruktur zu nutzen. So wird beispielsweise mit Storyboard.GetCurrentTime().Ticks der aktuelle Fortschritt der Animation berechnet.

Da die Startwerte der Animationen von der aktuellen Größe des Browser Fensters abhängen, muss man diese vor dem ersten Animationsschritt zunächst ermitteln. Außerdem muss man für bestimmte Elemente den GridUnitType ändern.

void StartMaximize()
{
  _lrc0Width = MainPage.LayoutRoot.ColumnDefinitions[0].ActualWidth;
  _lrc2Width = MainPage.LayoutRoot.ColumnDefinitions[2].ActualWidth;

  MainPage.LayoutRoot.ColumnDefinitions[0].Width = new GridLength(_lrc0Width);
  MainPage.LayoutRoot.ColumnDefinitions[1].Width = new GridLength(1, GridUnitType.Star);
  MainPage.LayoutRoot.ColumnDefinitions[2].Width = new GridLength(_lrc2Width);

  MainPage.InnerLayout.RowDefinitions[0].Height = new GridLength(100);
  MainPage.InnerLayout.RowDefinitions[1].Height = new GridLength(1, GridUnitType.Star);
  MainPage.InnerLayout.RowDefinitions[2].Height = new GridLength(30);
  MainPage.InnerLayout.ColumnDefinitions[0].Width = new GridLength(180);
  MainPage.InnerLayout.ColumnDefinitions[1].Width = new GridLength(1, GridUnitType.Star);
}

Nun kann bei jedem Redering Event die Größe der einzelnen Grids entsprechend skaliert werden. Die Animation sieht dabei insgesamt noch etwas geschmeidiger aus, wenn man den linearen Zeitverlauf durch eine Ease Funktion etwas modifiziert. Mit einem PowerEase Objekt wird die Bewegung kurz vor Erreichen der Endposition leicht abgebremst. Hier exemplarisch der Code für AnimateMaximize:

void AnimateMaximize(double progress)
{
  var factor = 1 - new PowerEase { EasingMode = EasingMode.EaseOut, Power = 3 }.Ease(progress);

  MainPage.LayoutRoot.ColumnDefinitions[0].Width = new GridLength(factor * _lrc0Width);
  MainPage.LayoutRoot.ColumnDefinitions[2].Width = new GridLength(factor * _lrc2Width);

  MainPage.InnerLayout.RowDefinitions[0].Height = new GridLength(factor * 100);
  MainPage.InnerLayout.RowDefinitions[2].Height = new GridLength(factor * 30);
  MainPage.InnerLayout.ColumnDefinitions[0].Width = new GridLength(factor * 180);
}

Für Restore ist die Implementierung analog.

Hier das Endergebnis zum Ausprobieren

Fazit

Zwar ist die Lösung letzlich ein Hack, funktioniert aber wesentlich besser als beispielsweise ein Rumtricksen mit einem DispatcherTimer. Der Animationscode ist komplett in einer eigenen Klasse versteckt und zieht sich nicht durch die Code Behind Datei. Außerdem werden durch die Verwendung des Rendering Events exakt so viele Animationsschritte berechnet, wie Silverlight in der entsprechenden Zeit Frames rendert. Das sorgt für einen ruckelfreien Verlauf.

Ein weiterer Vorteil in der direkten Animation der GridLenth Objekte liegt darin, dass keinerlei besondere Vorkehrungen im XAML Code gemacht werden müssen. So kann die Animation auch nachträglich in eine bestehende Anwendung eingebaut werden und es müssen keine Hilfsobjekte (wie Border oder etwas vergleichbares) nur zum Zweck der Animation eingeführt werden.

Das gezeigte Verfahren lässt sich leicht auf andere Situationen anpassen, bei denen Datentypen animiert werden müssen, für die es keine vordefinierten Animation gibt.

Hier der gesamte Quellcode zum Downloaden:

SilverlightGridAnimation.zip (16,10 kb)

Die Präprozessordirektive #line

09.11.2009 21:13:00 | Lars Schmitt

Präprozessordirektiven wie zb 

  • #region
  • #endregion
  • #if
  • #else
  • #endif
  • #warning

sollten mittlerweile die meisten Entwickler kennen, jedoch was ist zb mit der #line - Direktive.

Durch den Präprozessor Befehl #line hidden, werden aufeinander folgende, bis zur #line default Direktive, Quellcode Zeilen, vor dem Debugger verborgen.

Was bringt mir als Entwickler diese Direktive?

Der Vorteil für den Entwickler liegt darin, dass er beim Debuggen nicht immer wieder in Methoden wie zB. die überschrieben Methode WndProc eines Forms reinsteppt. (Welchem Entwickler, hat es noch nicht den letzten Nerv geraubt, wenn er beim Debuggen, immer wieder in diese Methode zu reinsteppt)


[code language=”C#”]

#line hidden
        protected override void WndProc(ref Message m)
        {
            …
            base.WndProc(ref m);
        }
#line default

[/code]

 

Der Vollständigkeits halber, noch einen weiterer Anwendungsfall, der der #line Direktive.

In diesem Beispiel zeuge ich, wie man mittels der #line Direktive, die Code Zeile und den Dateinamen in Fehler oder Warnungs Ausgaben manipulieren kann.

Falls ihr eine sinnvolle Verwendung findet, immer her damit, denn leider fällt es mir schwer, für diesen Präprozessor, eine wirklich sinnvolle Verwendung zu finden.

[code language=”C#”]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {

            int zahl = 0;

//#line Zeilennummer “Filename”  der Filename ist optional
#line 42 "Die Antwort aller Fragen, befindet sich in der QuellcodeZeile.cs"
            int neueZahl = 23 / zahl;
#line default

            Console.WriteLine();
        }
    }
}

[/code]

und an dieser Stelle, der dazugehörige Fehler:

at ConsoleApplication2.Program.Main(String[] args) in c:\Users\Lars\Documents\Visual Studio 2010\Projects\ConsoleApplication2\ConsoleApplication2\Die Antwort aller Fragen, befindet sich in der QuellcodeZeile.cs:line 42
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()

Microsoft TechEd Europe 2009 in Berlin erfolgreich eroeffnet ( #tee09 )

09.11.2009 19:00:45 | Kay Giza

Heute war ein wirklich interessante und schöner Tag, er eigentliche Beginn der TechEd Europe 2009!
Wie ich berichtete, bin ich am Windows 7 / Internet Explorer 8 Stand. Ich hatte heute viele interessante Gespräche und habe auch einige Fragen mitgenommen, die ich die nächsten Tage per  Weblog beantworten möchte.

Achim Berg, Vorsitzender der Geschäftsführung von Microsoft Deutschland, hat heute die TechEd Europe 2009 in Berlin eröffnet. Er begrüßte auf der ausverkauften Veranstaltung, die bis zum 13. November im Messezentrum stattfindet, insgesamt 6.800 Teilnehmer aus 104 Ländern. Neben Microsoft Exchange Server 2010, Windows 7 und Microsoft Server 2008 R2 werden zahlreiche Neuerungen für Entwickler vorgestellt. Die TechEd Europe bietet IT-Professionals und Entwickler an fünf Tagen insgesamt 322 Breakout Sessions sowie 300 Partner Sessions und Networking-Möglichkeiten.
 
In Ihren Eröffnungsreden gaben Dr. Said Zahedani, Senior Director der Developer Platform & Strategy Group der Microsoft Deutschland GmbH, der die Teilnehmer der TechEd heute in der Developer Keynote begrüßte sowie Achim Berg einen sehr persönlichen Rückblick auf das heutige historische Datum: "Wie Millionen andere Menschen saß auch ich am 9. November 1989 wie gebannt vor dem Fernseher und verfolgte live den Fall der Berliner Mauer.", so Berg. Entsprechend unterstützt Microsoft Deutschland das neue virtuelle Gesamtkunstwerk "BerlinMosaik", das die beiden Bekannten & Freunde Lars Beckmann und Sascha Ackermann zum Jubiläum gestartet haben. Microsoft ruft alle Nutzer auf, bei diesem Projekt mitzumachen.
 
Microsoft präsentiert auf der TechEd Europe 2009 zahlreiche Neuigkeiten für IT-Professionals sowie Entwickler. So ist ab sofort Forefront Protection 2010 für Exchange Server zur Absicherung der Geschäftsinformationen erhältlich. Testversionen von Forefront Protection 2010 und Exchange Server 2010 sowie weitere Informationen zu Windows 7, Windows Server 2008 R2 und Partner-Lösungen gibt es unter http://www.thenewefficiency.com.
 
Die Community Technology Preview für SQL Server 2008 R2 lässt sich nun unter http://www.microsoft.com/sqlserver/2008/en/us/how-to-buy.aspx herunterladen. Zur Erstellung von mehrsprachigen Websites und Client-Anwendungen gibt es Beta-Versionen von Microsoft Translator Widgets und APIs (Application Programming Interfaces) - welches ich hier im Weblog bereits nutze, mehr dazu im Team-Blog unter http://blogs.msdn.com/translation/. Zudem wird die Microsoft Trustworthy Computing Group neue Richtlinien herausgeben, die auch im Agilen Entwicklungsprozess die Integration des Secure Development Lifecycle (SDL)-Prozesses direkt in Softwareentwicklungsumgebungen ermöglicht. Damit erhalten Entwickler mehr Möglichkeiten, sichere Anwendungen zu erstellen.
 
Microsoft hat heute auch die Übernahme der Teamprise-Angebote von SourceGear LLC angekündigt.
 
Weitere Informationen zur Microsoft TechEd Europe 2009



This post is powered by www.Giza-Blog.de | Giza-Blog.de: RSS Feed
Visit:  MSDN Online | Follow MSDN Online on Twitter | Follow Kay Giza on Twitter
Daily News on MSDN:  MSDN Aktuell
© Copyright 2006-2010 Kay Giza. All rights reserved. Legal
Subscribe

Integration von Teamprise-Loesungen in Visual Studio 2010 ( #tee09 )

09.11.2009 18:53:59 | Kay Giza

Microsoft hat heute auch - währende der Developer Keynote gehalten von Dr. Said Zahedani und Jason Zander - die Integration der Teamprise-Angebote von SourceGear LLC in Visual Studio angekündigt .

Damit können Entwickler, die die Eclipse IDE nutzen oder auf multiplen Betriebssystemen inklusive Unix, Linux und Mac OS X arbeiten, Anwendungen mit Hilfe von Microsoft Visual Studio Team Foundation Server erstellen. Sie profitieren damit von verbesserter Integration in heterogene Umgebungen sowie kürzeren Entwicklungszeiten und höherer Produktivität. Die Funktionalität der Teamprise Client Suite wird in Visual Studio 2010 integriert sein. 

Mehr Informationen findet man in der englischsprachigen Presse-Mitteilung:
Microsoft Acquires Teamprise Assets, Provides Cross-Platform Support for Visual Studio



This post is powered by www.Giza-Blog.de | Giza-Blog.de: RSS Feed
Visit:  MSDN Online | Follow MSDN Online on Twitter | Follow Kay Giza on Twitter
Daily News on MSDN:  MSDN Aktuell
© Copyright 2006-2010 Kay Giza. All rights reserved. Legal
Subscribe

20 Jahre Mauerfall: Das Berlin-Mosaik (Fotos) - machen Sie mit! ( #TEE09 #20jmf )

09.11.2009 18:47:58 | Kay Giza

Achim Berg (Vorsitzender der Geschäftsführung von Microsoft Deutschland) und Said Zahedani (Senior Director Developer Platform and Strategy Group, Microsoft Deutschland), haben heute während Ihrer TechEd-Keynote etwas ganz besonderes vorgestellt. In ihren Reden stellte sie mit "BerlinMosaik" ein virtuelles Gesamtkunstwerk basierend auf Silverlight-Technologie vor, anlässlich des 20-jährigen Jubiläums des Mauerfalls .

In seiner Eröffnungsrede gab Achim Berg einen sehr persönlichen Rückblick auf das heutige historische Datum: "Wie Millionen andere Menschen saß auch ich am 9. November 1989 wie gebannt vor dem Fernseher und verfolgte live den Fall der Berliner Mauer." Entsprechend unterstützt Microsoft Deutschland das neue virtuelle Gesamtkunstwerk "BerlinMosaik", das die Bekannten & Freunde Lars Beckmann und Sascha Ackermann zum Jubiläum gestartet haben. Nutzer können dabei Fotos in unterschiedliche Communities wie Picasa, Twitter oder Flickr hochladen und den Tag "20jmf" einbinden. Eine von den Künstlern entwickelte Applikation findet die Bilder und gliedert sie in das Social Media-Projekt ein. Tausende von Fotos lassen sich dann gleichzeitig zoomen oder neu anordnen. Realisiert wird das innovative Projekt über die Microsoft-Technologie Silverlight 3 mit Deep Zoom. Microsoft ruft alle Nutzer auf, bei diesem Projekt mitzumachen.

Der Mauerfall am 9.11.1989 hat eindrucksvoll gezeigt, was eine große Gemeinschaft bewirken kann. Nur der Wille und die Hartnäckigkeit der demonstrierenden Massen haben die Wiedervereinigung möglich gemacht. Wir möchten jetzt, 20 Jahre später, dem Volk ein Gesicht geben und das größte Fotomosaik der Welt erschaffen. Jeder kann mithelfen und sich mit einem oder mehreren Bildern verewigen, um damit seinen Eindruck des Mauerfalls, der Feierlichkeiten zum 20 jährigen Jubiläum oder sonstigen Impressionen zu dem Thema allen Menschen mitteilen. Mehr Informationen zum BerlinMosaik und den Teilnahmemöglichkeiten gibt es unter http://www.citymosaic.de.



This post is powered by www.Giza-Blog.de | Giza-Blog.de: RSS Feed
Visit:  MSDN Online | Follow MSDN Online on Twitter | Follow Kay Giza on Twitter
Daily News on MSDN:  MSDN Aktuell
© Copyright 2006-2010 Kay Giza. All rights reserved. Legal
Subscribe

Exchange Server 2010 ab sofort verfuegbar ( #tee09 )

09.11.2009 18:40:02 | Kay Giza

Wow - welch ein Tag heute auf TechEd Europe in Berlin! Microsoft Exchange Server 2010 ist ab sofort weltweit verfügbar. Dies hat Stephen Elop, President der Microsoft Business Division, in seiner Keynote eben während der TechEd Europe 2009 in Berlin bekannt gegeben. Mit Hilfe von Exchange Server 2010 können Unternehmen Kosten reduzieren, ihre Kommunikation schützen und die E-Mail-Nutzung optimieren. Im gemeinsamen Einsatz mit Windows 7 und Windows Server 2008 R2 lässt sich die Produktivität nochmals erhöhen... [... mehr in diesem Blogeintrag auf Giza-Blog.de]

This post is powered by www.Giza-Blog.de | Giza-Blog.de: RSS Feed
Visit:  MSDN Online | Follow MSDN Online on Twitter | Follow Kay Giza on Twitter
Daily News on MSDN:  MSDN Aktuell
© Copyright 2006-2010 Kay Giza. All rights reserved. Legal
Subscribe

Auf der Tech·Ed Europe 2009 – Tag 1

09.11.2009 13:22:00 | Jan Schenk



tweetmeme_url = 'http://blogs.msdn.com/jansche/archive/2009/11/09/auf-der-tech-ed-europe-2009-tag-1.aspx'; tweetmeme_source = 'jansche';

tee09_TLC_stitch

Tag Eins der TechEd Europe 2009 ist rum und ich habe heute keinen Vortrag gehabt, dafür Zeit, ein bisschen was für msdn tv zu drehen und Sessions zu besuchen. Natürlich war ich auf einen Sprung bei David Chappell’s “The Windows Azure Platform – When and How to Use it” und ich bin immer wieder beeindruckt, von der Eloquenz, mit der er präsentiert. Ihr merkt schon, ich bin Fan von David Chappell. Und ich werde nicht müde es zu wiederholen: Wer die Chance bekommt, ihn auf der Bühne zu sehen, sollte sie unbedingt wahr nehmen.

_MG_9523 _MG_9519

Im TLC, dem Technical Learning Center, auf der TechEd Europe, habe ich Tom Wendel und Uwe Baumann getroffen, die als Vertreter der AntMe!-Fraktion vor Ort sind und fleissig aufgebaut haben. Bei ihnen kann man alles zum Thema Code4Fun und “Spielend Programmieren lernen” erfahren.

_MG_9533 _MG_9536

Und natürlich war ich auch kurz bei Frank “DR.MOBILE” Prengel, der mit Windows CE spannende Echtzeit-Anwendungen zeigt. Im Plexiglas-Kasten hat er ein umgedrehtes Pendel dabei, das mit einem Windows CE Server und weiteren CE-basierten Geräten in der Waage gehalten wird und trotzdem verschiedene geometrische Figuren abbilden kann.

_MG_9560 _MG_9560

Und das war bisher alles nur der Vormittag. Leider muss ich noch ein bisschen was arbeiten um meine Session morgen früh – SVR202 “Windows Azure Flight Tour – Looking at the Clouds from Above” – zu perfektionieren.

Wenn ihr mich auf der TechEd Europe treffen wollt, um mich zu poken, mit mir zu schnacken oder was auch immer, ich bin wie immer der mit dem Hut ;-). Ich seh euch in meiner Session oder ihr schreibt mir eine kurze E-Mail an jan_DOT_schenk @ microsoft DOT com.

jan

BizTalk Naming Conventions

09.11.2009 11:26:30 | Thorsten Hans

Biztalk_sml_3

Wenn man Projekte auf Basis von Microsofts BizTalk Server realisiert werden die entsprechenden Solutions in Visual Studio schnell sehr komplex und unübersichtlich, daher sollte man bevor man mit der Realisierung eines BizTalk Projektes beginnt sich unbedingt Gedanken über das Naming der einzelnen Komponenten machen.

 

Hier findet Ihr eine Liste mit guten Conventions nach denen man bei der Entwicklung vorgehen sollte, um auch bei einem späteren Review wieder schnell alles nötige zu finden.

 

 

Technorati-Tags: ,
DotNetKicks-DE Image

Grid Spalten von 2 unabhängigen Grids Syncronisieren

09.11.2009 09:29:00 | Lars Schmitt

Um in einer WPF Anwendung, die Spaltenbreiten von Zwei normalerweise voneinander unabhängigen Grids, auf eine Identische Größe zu bekommen. Sollte man nicht allzu vorschnell dazu übergehen, die jeweiligen Spaltenbreiten auf eine Fixe Größe zu setzten.

 

ohneSharedSize

an dieser Stelle kann man sehen, dass die beiden Gridspalten mit dem Inhalt ‘Text’ und ‘Dies ist ein langer Text’, leider unterschiedliche Größen haben, aus Design Technischen Gründen jedoch sollten diese beiden Spalten gleich groß sein.

 

Für diesen Anwendungsfall, bietet das WPF eine relativ einfache Möglichkeit.

Mithilfe des Property SharedSizeGroup in zb einer ColumnDefinition, können verschiedenen Gruppen über verschiedene Grids hinweg angelegt werden.

Die Grid's synchronisieren dann untereinander, ihre jeweiligen mit Gruppen benannten Spalten.


Hint: am Rande noch ein kleiner Tip, die Spalten Größen Zuweisung mit dem Joker (oder Star) Zeichen wird bei einer gesetzten SharedGroup als Auto Interpretiert.


  

<Window x:Class="WpfApplication1.Window1"   

    xmlns="<a href="http://schemas.microsoft.com/winfx/2006/xaml/presentation"">http://schemas.microsoft.com/winfx/2006/xaml/presentation"</a  

    xmlns:x="<a href=">http://schemas.microsoft.com/winfx/2006/xaml"">http://schemas.microsoft.com/winfx/2006/xaml"</a  

    Title="Window1" Height="300" Width="300">   

    <StackPanel<strong> </strong>Grid.IsSharedSizeScope="True">   

        <Grid ShowGridLines="True" >   

            <Grid.ColumnDefinitions>   

                <ColumnDefinition Width="Auto" SharedSizeGroup="FirstColumn"/>   

                <ColumnDefinition Width="Auto"/>   

                <ColumnDefinition Width="*"/>   

            </Grid.ColumnDefinitions>   

            <TextBlock>Text</TextBlock>   

            <TextBlock Grid.Column="1">tt</TextBlock>   

            <TextBlock Grid.Column="2">tt</TextBlock>   

        </Grid>   

        <Grid ShowGridLines="True">   

            <Grid.ColumnDefinitions>   

                <ColumnDefinition Width="Auto" SharedSizeGroup="FirstColumn"/>   

                <ColumnDefinition Width="Auto"/>   

                <ColumnDefinition Width="*"/>   

            </Grid.ColumnDefinitions>   

            <TextBlock>langer Text</TextBlock>   

            <TextBlock Grid.Column="1">tt</TextBlock>   

            <TextBlock Grid.Column="2">tt</TextBlock>   

        </Grid>   

    </StackPanel>   

</Window>  

mitSharedSize

Obwohl der Text in der ersten Spalte doch sehr kurz ist, ist die Spaltengröße nun identisch mit der ersten Spalte des Zweiten Grids.

Windows 7 und IE8 Stand auf der: Microsoft Tech·Ed Europe 2009 | #tee09

08.11.2009 19:59:37 | Kay Giza

Die Berliner sind freundlich (lässt mich der Busfahrer bewusst umsonst mitfahren), die Stadt ist im "20 Jahre-Mauerfall-Fieber" und alles ist trotz der enormen Hektik irgendwie ruhig und entspannt.
So auch auf der Tech·Ed, wo ich eben den Windows 7 und Internet Explorer 8 Stand begutachtet habe. Dort findet man mich übrigens die kommende Woche:

Wo genau?
Microsoft® Tech·Ed Europe 2009 | 9-13 November 2009, Berlin, Germany
Internet Explorer 8 / Windows 7 Stand
Halle 3 (nicht zu verfehlen, ist der erste Stand ;-) in der Halle)
2 Etage
Im Technical Learning Center (TLC, ehemals Ask the Experts)
Ausgeschildert als: 3.2

Ich freue mich auf eine interessante Woche, mit vielen interessanten und spannenden Gesprächen mit Kunden aus ganz Europe und natürlich auch Deutschland.
Speziell für die deutschen Kunden (weil der Inhalt auf Deutsch) habe ich einige interessante "Give-Aways" mitgebracht. Es lohnt sich also am Internet Explorer 8 (IE8) Stand auf der TechEd vorbei zu schauen.

Ab morgen werden ich versuchen regelmäßig über die TechEd Europe hier zu berichten, ob und wie es mir gelingt wird sich zeigen.



This post is powered by www.Giza-Blog.de | Giza-Blog.de: RSS Feed
Visit:  MSDN Online | Follow MSDN Online on Twitter | Follow Kay Giza on Twitter
Daily News on MSDN:  MSDN Aktuell
© Copyright 2006-2010 Kay Giza. All rights reserved. Legal
Subscribe

Auf der Tech·Ed Europe 2009 – Tag 0

08.11.2009 18:59:00 | Jan Schenk



tweetmeme_url = 'http://blogs.msdn.com/jansche/archive/2009/11/08/auf-der-tech-ed-europe-2009-tag-0.aspx'; tweetmeme_source = 'jansche';

Tag Null auf der Tech·Ed Europe 2009 ist gerade zu Ende gegangen. Tag Null deshalb, weil heute der Check-In Tag war, an dem aber auch schon Sessions stattgefunden haben. So auch meine “Windows Azure Platform Overview”-Session, kurz DEV101-SUN. Ich habe einen Talk zu den Very Basics von Cloud Computing und der Windows Azure Platform gehalten. Etwas, von dem ich vor einem knappen Jahr dankbar gewesen wäre, zu bekommen. Inzwischen ist einige zeit vergangen, und ich weiss natürlich viel mehr als damals, sonst hätten mich meine Kollegen Holger Sirtl und Dirk Primbs auch nicht auf die TechEd-Bühne gestellt. Denn: Die TechEd ist beeindruckend. Groß. Gewaltig. Selbst am Tag Null, dem Sonntag vor dem offiziellen Start der TechEd Europe 2009, wird einem das schiere Ausmaß der Veranstaltung bewusst. mehr als 6000 Menschen, unzählige Quadratmeter an Sessionräumen, Austellungsfläche und Erholungsbereiche. Und ich mitten drin. Was soll ich sagen, ich bin überwältigt, und stolz, hier sprechen zu dürfen. Sowas bin ich sonst nur von den US-amerikanischen Kollegen gewöhnt. Oder eben von Messen, aber das ist eine ganz andere Liga. Die Leute sind auf der TechEd wegen eben diesen Vorträgen, Hands-on-Labs und Diskussionen. Und natürlich dem Networking.

So habe ich heute auch eine extrem nette Erfahrung machen dürfen. Nach der Session über die Windows Azure Plattform kam ein Konferenzbesucher und – nachdem er mir einige Fragen gestellt hatte – fragte er mich noch, ob er mich denn auch wirklich kontaktieren dürfe. Ich hatte ihm zuvor meine Visitenkarte gegeben. Ob das dann nicht auch mit Kosten verbunden wäre. Der Gute meinte, wir würden ihm vielleicht eine Rechnung stellen, wenn er mich per E-Mail kontaktiert. Ich habe mich fast ein bisschen geschämt, dass diese Annahme da draussen überhaupt existiert.

Für alle: Die Dienste eines Evangelisten, sei es als Anfrage über meinen Blog, Kontakt auf Konferenzen oder anderen Veranstaltungen kosten nichts. Ich freue mich über jede E-Mail und versuche alle möglichst zeitnah zu beantworten. Aber bevor ich euch zum Support schicke, der dann in einigen wenigen Fällen auch tatsächlich mit Kosten verbunden ist, versuchen wir alles in unserer Macht stehende zu tun, um eure Anfragen zu beantworten! Und ihr erfahrt auf jeden Fall rechtzeitig, wann Kosten auf euch zu kommen. Versprochen!

Ich freue mich jetzt morgen auf einen Tag TechEd, den ich geniessen kann, denn meine nächste Session ist erst am Dienstag. Dafür allerdings um 9 Uhr morgens. Morgen Abend ist dann noch das zwanzigjährige Jubiläum des Berliner Mauerfalls. Dazu übrigens sehr zu empfehlen: http://www.citymosaic.de. Dort gibt es aktuelle Bilder der Feierlichkeiten in einem grossartigen DeepZoom-Projekt. Ihr könnt euch unter diesem Begriff nichts vorstellen? Dann unbedingt mal reinschauen.

Alle wichtigen Infos zur TechEd Europe findet ihr unter: http://www.microsoft.com/teched.

Bis morgen, dann gibt es auch ein paar Bilder!
jan

Double Content durch normalisierte URLs

08.11.2009 12:51:46 | Klaus Bock

In letzter Zeit fielen mir bei der Überprüfung meines Blog in den Google Webmaster-Tools vermehrte Hinweise auf Double Content auf. Die Ursache war schnell gefunden. Jede angemahnte Seite war mit zwei URLs vertreten: einmal mit der original URL und einmal mit einer URL komplett in Kleinschreibung. Für dieses Verhalten konnte nur einer der zahlreichen Bookmark-Dienste verantwortlich sein. Leider konnte ich nicht ermitteln woher die URLs stammten, da die Quelle nicht angezeigt wird. Da die Ursache nicht entfernt werden konnte, muss an der Wirkung gearbeitet werden.

ASP.NET basierende Anwendungen betrachten by Design URLs in unterschiedlicher Schreibweise als gleich. Es macht also keinen Unterschied ob Das-ist-die-selbe-Seite.aspx oder das-ist-die-selbe-seite.aspx aufgerufen wird. Es wird beide male die gleiche Seite angezeigt. Dieses Verhalten ist für den Anwender eigentlich nicht schlecht, da er nicht auf Groß- und Kleinschreibung achten muss. Für eine Suchmaschine ist dieses Verhalten jedoch der gleiche Inhalt unter verschiedenen URLs; also Double Content.

Im Falle meines Blog, der auf Blogengine.NET basiert, war die Lösung des Problems relativ einfach. Bei der Anforderung einer URL musste ich lediglich die angeforderte URL des jeweiligen Artikel mit der gespeicherten URL aus dem Post-Objekt vergleichen. Sind diese nicht identisch, wird eine permanente Umleitung, Statuscode 301, mit der URL aus dem Post-Objekt an den Client gesendet. Folgende Anpassung ist dabei in der Datei post.aspx.cs im Wurzelverzeichnis der Anwendung vorzunehmen. Die Zeilennummern im Listing entsprechen dabei den Zeilennummern in der Datei.

// verhindert double content durch
// unterschiedliche Schreibweise der URL
string requestUri = this.Request.RawUrl.Substring(
		Request.RawUrl.LastIndexOf('/') + 1);
string postUri = this.Post.RelativeLink.Substring(
		Post.RelativeLink.LastIndexOf('/') + 1);

if (!postUri.Equals(requestUri, StringComparison.Ordinal))
{
    this.Response.Clear();
    this.Response.StatusCode = 301;
    this.Response.AppendHeader(
		"location",
		Post.RelativeLink.ToString());
    this.Response.End();
}

Anwender die auch Pages unter Blogengine.NET verwenden, sollten natürlich auch die Datei page.aspx.cs, ebenfalls im Wurzelverzeichnis zu finden, entsprechend anpassen.

Die kleine Änderung im Code zeigte Wirkung, denn nach ein paar Tagen waren keine Hinweise mehr auf Double Content in den Google Webmaster-Tools zu finden.

Technorati-Tags: | | |

How-To's für WPF und Silverlight

07.11.2009 23:28:09 | Norbert Eder

Kleine How-To's, also kleine Artikel, die kompakt die Lösung eines Problems zeigen, können sehr hilfreich sein. .NET GUI bietet hierfür eine eigene Sektion an, die sich langsam aber sicher mit zahlreichen How-To's füllt. Nun sind vier weitere How-To's verfügbar: Windows7-Taskbar mit WPF anpassen - Progress Windows7-Taskbar mit...

Download: Paint.NET 3.5 finale Version [Bildbearbeitungsprogramm, Freeware]

07.11.2009 17:56:48 | Kay Giza

Es ist so weit :-): mein Lieblings-Bildbearbeitungs-Tool Paint.NET ist endlich in der finalen Version 3.5 erschienen: Paint.NET v3.5 Final. Genauer gesagt ist die Version Paint.NET v3.5 (Final Release Build 3.50.3596.41598) erschienen. Neben neuen Effekten beeindruckt das schnelle und kostenfreie Bildbearbeitungsprogramm nun durch ein frisches und neues Programmdesign. Weiterhin hat man sich Mühe gegeben die von Windows Vista und Windows 7 bereitgestellten visuellen Effekte zu nutzen, wie z.B. Aero und "Glass". Es wurden sehr viele Verbesserungen vorgenommen, Schnelligkeit und somit Performance standen dabei sehr häufig im Vordergrund. So nutzt Paint.NET z.B. unter Windows 7 bei dem Text-Tool DirectWrite anstatt GDI - was nun alles erheblich schneller geht :) Insgesamt kommt das Wort "Performance" sehr häufig in der Liste der Neuerungen vor. Weiterhin ist natürlich erwähnenswert das es ein neues Menü "Utilities" gibt, wo man nun u.a. die Update-Suche starten kann sowie die Sprache und Plug-Ins verwalten kann. Apropos Sprache, unsere Freunde aus Russland können Paint.NET nun auch in Ihrer Muttersprache nutzen. Die vollständige Liste der Neuigkeiten im Vergleich zur Version 3.36, einen Download-Link, Screenshots sowie weiterführende Informationen finden Sie in diesem ausführlichen Blog-Eintrag auf Giza-Blog.de ... [...mehr]

This post is powered by www.Giza-Blog.de | Giza-Blog.de: RSS Feed
Visit:  MSDN Online | Follow MSDN Online on Twitter | Follow Kay Giza on Twitter
Daily News on MSDN:  MSDN Aktuell
© Copyright 2006-2010 Kay Giza. All rights reserved. Legal
Subscribe

Der leidenschaftliche Programmierer

07.11.2009 16:10:49 | Klaus Bock

Der leidenschaftliche Programmiererlautet der Titel des Buches, welches mir kürzlich in die Hände fiel.
Chad Fowler, die meisten Ruby-Entwickler dürften ihn kennen, hat mit diesem Buch kein technisches Werk zu einer der vielen Programmiersprachen verfasst, sondern geht viel mehr auf die größeren und kleineren Probleme im Berufsalltag eines Softwareentwicklers ein. In den 53 kurzen, aber sehr prägnanten, Artikeln greift er die verschiedensten Szenarien auf und gibt allerlei Tipps um die ein oder andere Situation zu meistern.
Man merkt während des Lesens sehr schnell, dass Chad Fowler auf einen reichen Erfahrungsschatz zurückgreifen kann. Da Chad Fowler eigentlich Musiker ist, zieht er immer wieder Parallelen zu diesem Metier und schafft dabei auf anschauliche Art und Weise Verbindungen die für jeden nachvollziehbar sind. Viele dieser Situationen lassen sich problemlos auf alle möglichen Berufe übertragen, genauso wie der jeweilige Lösungsansatz.

Erwähnenswert sind auch die zahlreichen Anekdoten aus dem Bekanntenkreis des Autors. Eine davon, die mir persönlich am besten gefiel, ist die Schilderung von Tom Preston-Werner wie er ein sehr lukratives Angebot von Microsoft ausschlug um mit GitHub “etwas cooles zu tun”. Der Titel der Anekdote könnte passender nicht sein:
Wie ich 300.000$ von Microsoft ablehnte, um in Vollzeit an GitHub zu arbeiten.

So unterhaltsam wie teilweise die enthaltenen Anekdoten sind, so aussagekräftig sind die Titel der einzelnen Kapitel gehalten. Wie etwa der Titel des ersten Kapitel der da lautet: Führen oder bluten? Der Autor verdeutlicht in diesem ersten Artikel an zahlreichen Beispielen die noch heutige Gültigkeit des alten Leitsatz: “Geringes Risiko. Geringe Belohnung.”

Das Buch liest sich sehr leicht und unterhaltsam, ist dabei jedoch keineswegs als leichte Unterhaltung zu verstehen. Vielmehr versucht der Autor dem Leser die Augen zu öffnen und die Aufmerksamkeit auf die eigene persönliche Entwicklung des Lesers zu lenken. Er zeigt interessante Betrachtungsweisen ungeliebter Aufgaben und schafft dabei neue Perspektiven. Anhand anschaulicher Beispiele werden Möglichkeiten gezeigt, die der ein oder andere so für sich noch nicht in Betracht gezogen haben mag. Wie der Titel schon erahnen lässt, versucht Chad Fowler den leidenschaftlichen Programmierer im Softwareentwickler zu wecken.

Meine Leidenschaft für das Programmieren bedurfte keines Erweckens, denn sie ist nie erlöschen. Vieleicht auch, weil ich nie den Zwängen eines professionellen Entwicklers unterworfen war. Ich musste mich nie mit Deadlines und unmöglichen Kundenwünschen herumschlagen.
Der Autor, der ja selbst Entwickler ist, kennt das Entwicklergeschäft allerdings sehr gut. Ich kann mir gut vorstellen, dass es bestimmt Entwickler da draußen gibt, deren Leidenschaft für ihren Job sanft entschlafen ist; oder der ein oder andere nur noch Code schreibt, damit “Belag auf die Pizza” kommt. Alle die sich jetzt angesprochen fühlen, sollte einmal einen Blick in dieses Buch riskieren.

Auch alle anderen, deren Neugier geweckt wurde, können sich einen eigenen Eindruck bei einer Leseprobe unter http://www.it-fachportal.de/5885 verschaffen.
Mir hat es sehr viel Spaß bereitet das Buch zu lesen, konnte aber auch den ein oder anderen Rat mitnehmen.

Reporting Services über einen NLB-Cluster betreiben

07.11.2009 11:42:05 | Thomas Schissler

Mit dem TFS 2010 ist es nun möglich, denn Application-Tier über einen NLB-Cluster zu betreiben. Damit kann man Ausfallsicherheit und Load-Balancing für den App-Tier erreichen. Mit einem SQL-Cluster als Data-Tier skaliert der TFS nun sehr schön, sowohl in Punkte Performance als auch in Bezug auf die Ausfallsicherheit.

image

Nun liegt es natürlich nahe, die Reporting Services ebenfalls über den NLB zu betreiben, was an sich auch kein Problem ist. Man muss nur ein paar Einstellungen vornehmen. So hats bei mir funktioniert:

1.) Das Scale-out Deployment für die Reporting-Services auf beiden Servern aktivieren (setzt SSRS Enterprise voraus)

image

2.) Die Web Service URL auf die IP-Adresse des NLB einstellen

image

3.) In der TFS Admin Console die Reporting Services über den NLB registrieren. Das hat bei mir nur über die IP-Adresse funktioniert, nicht über den Namen. Da muss ich bei Gelegenheit mal danach schauen.

image

4.) In der Datei C:\Program Files\Microsoft SQL Server\MSRS10.MSSQLSERVER\Reporting Services\ReportServer\rsreportserver.config unter <Service> folgendes Tag einfügen:

<Hostname>sartfsnlb01</Hostname>

5.) In der Web.config unter C:\Program Files\Microsoft SQL Server\MSRS10.MSSQLSERVER\Reporting Services\ReportServer\ und unter C:\Program Files\Microsoft SQL Server\MSRS10.MSSQLSERVER\Reporting Services\ReportManager\ im Abschnitt <system.web> folgenden Tag einfügen:

<machineKey validationKey="627BF72BB33AA8D28CA2C3E80920BA4DF0B726F97EEFBB0F4818350D63E6AFA380811F13ED1F086E386284654DB3DAF676707464EEB73EBF79858F477D8E4F5C"
decryptionKey="F40B6E5A02B29A181D2D213B5ED8F50B73CFCFD0CC56E137" validation="SHA1" />

Achtung die Parameterwerte dürfen nuicht umgebrochen werden. Einen eigenen Key kann man sich einfach unter http://aspnetresources.com/tools/keycreator.aspx generieren lassen.

6.) Reporting Srevices neu starten.

7.) Nun werden bei einem Ausfall eines App-Tiers alle Reporting-Anfragen über den anderen App-Tier abgewickelt, der Anwender merkt davon nichts außer dass es beim ersten Zugriff nach dem Ausfall ein wenig länger dauert.

TechEd in Berlin

07.11.2009 08:15:43 | Thomas Schissler

Dieses Jahr ist nach längerer Zeit die TechEd, die wichtigste Microsoft-Konferenz in Europa, wieder in Deutschland, genauer gesagt vom 09.Nov – 13. Nov in Berlin. Ich werde dort als ATE (Ask the Experts) zum Thema Visual Studio ALM vertreten sien und darüber hinaus mit Christian Binder und Neno Loje ein Q&A Session zu den Themen TFS, ALM und Visual Studio 2010 zu machen. Die Session wird in Deutsch sein, also wenn ihr Fragen rund um den Themenbereich habt, besucht unsere Q&A-Session. Soviel geballtes Wissen auf einmal gibts nicht so bald wieder :-)

Visual Studio Team Foundation Server Q&A
Mittwoch, 11. November
14:00 – 15:00 Uhr
Community Stage im Zentrum der Ausstellung Halle 4.2

WPF MultiBinding

07.11.2009 02:23:00 | Lars Schmitt

Es kann ja immer mal wieder passieren, dass man zb an einer TextBox nicht mit einem Binding auskommt. Für diesen Anwendungsfall, gibt es das Multibinding


Dieses kann zb dazu verwendet werden, um eine Vielzahl von Daten zu einem ganzen zu konvertieren, um dieses Ergebnis in einer WPF TextBox anzeigen zu lassen.


Angewendet kann das ganze entweder, für viele Fälle schon ausreichend mit dem StringFormat 

Quelle

  

<?xml version="1.0" encoding="utf-8" ?>   
<Source>    
  <Item>    
    <Vorname>Lars</Vorname>    
    <Nachname>Schmitt</Nachname>    
  </Item>    
</Source>  

 

XAML

  

<Window x:Class="WpfApplication7.MainWindow"   
        xmlns="<a href="http://schemas.microsoft.com/winfx/2006/xaml/presentation"">http://schemas.microsoft.com/winfx/2006/xaml/presentation"</a    
        xmlns:x="<a href=">http://schemas.microsoft.com/winfx/2006/xaml"">http://schemas.microsoft.com/winfx/2006/xaml"</a    
        Title="MainWindow" Height="350" Width="525">   

    <Window.Resources>   
        <XmlDataProvider x:Key="data" XPath="Source/Item" Source="Source.xml" />    
    </Window.Resources>   

    <Grid VerticalAlignment="Center" HorizontalAlignment="Center">   
        <TextBox DataContext="{StaticResource data}">    
            <TextBox.Text>    
                <MultiBinding StringFormat="{}{1}, {0} alias Blackcoin">    
                    <Binding XPath="Vorname"/>    
                    <Binding XPath="Nachname"/>    
                </MultiBinding>    
            </TextBox.Text>    
        </TextBox>    
    </Grid>    
</Window>  

 

Multibinding

 

das ganze kann aber natürlich auch, mit Hilfe eines einem IMultiValueConverter konvertiert werden.


 

  

using System;   
using System.Collections.Generic;    
using System.Linq;    
using System.Text;   

namespace WpfApplication7   
{    
    public class StringFormatConverter : System.Windows.Data.IMultiValueConverter    
    {    
        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)    
        {    
            try    
            {    
                return values[1].ToString()+ ", "+values[0].ToString();    
            }    
            catch { return ""; }    
        }   

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)   
        {    
            return value.ToString().Split(',');    
        }    
    }    
}

 

  

<Window x:Class="WpfApplication7.MainWindow"   
        xmlns="<a href="http://schemas.microsoft.com/winfx/2006/xaml/presentation"">http://schemas.microsoft.com/winfx/2006/xaml/presentation"</a    
        xmlns:x="<a href=">http://schemas.microsoft.com/winfx/2006/xaml"">http://schemas.microsoft.com/winfx/2006/xaml"</a    
        xmlns:local="clr-namespace:WpfApplication7"    
        Title="MainWindow" Height="350" Width="525">   

    <Window.Resources>   
        <XmlDataProvider x:Key="data" XPath="Source/Item" Source="Source.xml" />    
        <local:StringFormatConverter x:Key="Converter"/>    
    </Window.Resources>   

    <Grid VerticalAlignment="Center" HorizontalAlignment="Center">   
        <TextBox DataContext="{StaticResource data}">    
            <TextBox.Text>    
                <MultiBinding Converter="{StaticResource Converter}">    
                    <Binding XPath="Vorname"/>    
                    <Binding XPath="Nachname"/>    
                </MultiBinding>    
            </TextBox.Text>    
        </TextBox>    
    </Grid>    
</Window>

MSDN TV: Ausgabe 06.11.09 - inkl. einem Interview mit Hannes Preishuber

06.11.2009 19:04:53 | Kay Giza

Für die aktuelle Folge von „MSDN TV“ hatte Moderator Jan Helmhut Schenk Gelegenheit, mit Hannes Preishuber zu sprechen, dem Vorstand des IT-Weiterbildungsspezialisten ppedv AG. Natürlich geht’s dabei u.a. um die anstehende Entwicklerkonferenz VSOne, die im Februar 2010 in München stattfindet, aber auch ums Trainingsbusiness im allgemeinen, um Technikvorlieben und um Pro & Contra Open Source. In den Kurzmeldungen: die Beta 2 von Visual Studio 2010 und .NET 4.0, der erste Geburtstag von Small Basic, Neues zur Microsoft Press Preview, die Online-Trainings der Weiterbildungsinitiative LiftOff und die integrierte Entwicklungsumgebung Eclipse zur Verbesserung der Interoperabilität von Windows 7, Windows Azure und Silverlight [11:37].

Gaaaanz wichtig sei noch zu erwähnen, es gibt Dank dieser MSDN TV-Folge sogar etwas zu gewinnen :-) - was genau und wie es geht - erfährt man in dem Video!


MSDN TV mit Hannes Preishuber

Hier gibts MSDN TV: Ausgabe 06.11.09

PS: Meinen Dank möchte ich an dieser Stelle mal an das MSDN Online-Team sowie natürlich Jan Schenk aussprechen, für all die interessanten MSDN TV-Folgen!



This post is powered by www.Giza-Blog.de | Giza-Blog.de: RSS Feed
Visit:  MSDN Online | Follow MSDN Online on Twitter | Follow Kay Giza on Twitter
Daily News on MSDN:  MSDN Aktuell
© Copyright 2006-2010 Kay Giza. All rights reserved. Legal
Subscribe

Professionals im Profil - Interview von Golo Roden mit mir

06.11.2009 17:58:00 | Peter Bucher

Golo Roden hat mit http://www.professionals-im-profil.net/ ein Projekt gestartet, wo er berufstätige Entwickler interviewt, unter anderem mit der Frage, wie man den Einstieg ins Berufsleben geschafft hat und vorallem woher man die Motivation nimmt, immer neue Dinge zu lernen.

Softwareentwicklung ist ein faszinierendes Thema – keine Frage. Doch wie gelingt der Einstieg? Wie und womit sollte man beginnen? Woher die Motivation und die Energie nehmen, auf Dauer beständig Neues zu lernen? Welche Voraussetzungen sollte man als Anfänger überhaupt erfüllen, um auf Dauer erfolgreich sein zu können?

All diese Fragen beschäftigen jene, die heute versuchen, einen vernünftigen Einstieg in die Softwareentwicklung zu finden.

Doch diese Fragen haben auch all jene beschäftigt, denen der Einstieg bereits gelungen ist und die sich inzwischen professionell – entweder beruflich oder in der Community – mit Softwareentwicklung beschäftigen.

Warum also nicht einfach fragen, wie es ihnen bei ihrem Einstieg ergangen ist? Welche Hürden sie zu überwindern hatten, welche Erfolgserlebnisse sie hatten, und woher sie ihre Motivation genommen haben?

Dies ist die Idee von .NET Professionals im Profil: Die Webseite enthält Interviews zu diesem Thema mit Personen, die im Bereich .NET professionell tätig sind und sich beruflich oder in der Community einen Namen gemacht haben.

Für mich ist es eine Ehre, sich als ersten den Fragen von Golo stellen zu dürfen und ich freue mich schon auf die folgenden Interviews.
Das Interview mit mir ist unter http://www.professionals-im-profil.net/Peter-Bucher.aspx zu finden.

Viel Spass!

Ab 15.11.2009: MSDN Telefon-Hotline ändert Servicezeit

06.11.2009 12:23:22 | Peter Kirchner

MSDN Hotline

Die kostenfrei nutzbare MSDN Service Hotline ändert Ihre „Öffnungszeiten“.

Ab 15. November 2009 ist die Hotline von 12.00 – 18.00 Uhr für Sie verfügbar.

Nutzen Sie die telefonische Auskunft rund um das Microsoft Developer Network (MSDN) und andere Microsoft-Entwicklerthemen. Ziel der für Sie kostenlosen MSDN Hotline ist es, Ihnen bei der Orientierung im Microsoft-Angebotsspektrum für Entwickler behilflich zu sein und Sie beim Auffinden nützlicher Entwickler-relevanter Ressourcen zu unterstützen. Detaillierte Informationen sowie Telefonnummern finden Sie auf http://www.msdn-online.de/Hotline. Die interessantesten und häufig wiederkehrenden Anfragen werden vom Hotline Team im MSDN Forum zur Verfügung gestellt.

TechEd 2009 Berlin : Visual Studio Team Foundation Server 2010 Q&A in Deutsch

06.11.2009 12:04:10 | Christian Binder

Nächste Woche ist TechEd in Berlin :-) Da die TechEd nach langer Zeit wieder in Deutschland ist, haben wir, die Deutschen Team System MVP’s, Neno Loje, Thomas Schissler und Ich uns entschieden eine Deutsche Q/A anzubieten. Gebt uns Euer Feedback und bringt Fragen mit :-)

Date:     Wednesday, November 11th
Time:     2:00-3:00
Title:     Visual Studio Team Foundation Server Q&A in German
Location: Community Stage in the center of the Exhibition Hall 4.2.

clip_image002 

Chris

MSDN Telefon-Hotline mit neuer Servicezeit ab 15. November 2009

06.11.2009 10:58:02 | Kay Giza

Hallo zusammen,
wir haben uns entschieden, die "Öffnungszeiten" der MSDN Hotline zu ändern.
Mit dieser Änderung reagieren wir auf vielfachen Kundenwunsch, die Servicezeit der Hotline anzupassen und eher in die späten Nachmittagsstunden zu verlagern. Wir bedanken uns bei allen Kunden, die uns hier stetig Feedback über die MSDN Hotline zukommen lassen. Vielen Dank, dieser Dialog ist nicht selbstverständlich.

Die kostenfrei nutzbare MSDN Service Hotline ändert Ihre Service-Zeit: Ab 15. November 2009 ist die Hotline von 12.00 – 18.00 Uhr für Sie verfügbar. Nutzen Sie die telefonische Auskunft rund um das Microsoft Developer Network (MSDN) und andere Microsoft-Entwicklerthemen. Ziel der für Sie kostenlosen MSDN Hotline ist es, Ihnen bei der Orientierung im Microsoft-Angebotsspektrum für Entwickler behilflich zu sein und Sie beim Auffinden nützlicher Entwickler-relevanter Ressourcen zu unterstützen. Detaillierte Informationen sowie Telefonnummern finden Sie auf http://www.msdn-online.de/Hotline. Die interessantesten und häufig wiederkehrenden Anfragen werden von dem Hotline Team im MSDN Forum zur Verfügung gestellt.

Mehr Informationen: MSDN Telefon-Hotline ändert Service-Zeit
MSDN Hotline

Weiterführende Links:

 



This post is powered by www.Giza-Blog.de | Giza-Blog.de: RSS Feed
Visit:  MSDN Online | Follow MSDN Online on Twitter | Follow Kay Giza on Twitter
Daily News on MSDN:  MSDN Aktuell
© Copyright 2006-2010 Kay Giza. All rights reserved. Legal
Subscribe

msdn tv – Nachrichten für Entwickler (Ausgabe vom 06.11.2009) mit Gewinnspiel

06.11.2009 10:27:38 | Jan Schenk



tweetmeme_url = 'http://blogs.msdn.com/jansche/archive/2009/11/06/msdn-tv-nachrichten-f-r-entwickler-ausgabe-vom-06-11-2009-mit-gewinnspiel.aspx'; tweetmeme_source = 'jansche';

Get Microsoft Silverlight

Für die aktuelle Folge von „msdn tv“ hatte Moderator Jan Helmhut Schenk Gelegenheit, mit Hannes Preishuber zu sprechen, dem Vorstand des IT-Weiterbildungsspezialisten ppedv AG (Burghausen). Natürlich geht’s dabei u.a. um die anstehende Entwicklerkonferenz VSOne, die im Februar 2010 in München stattfindet, aber auch ums Trainingsbusiness im allgemeinen, um Technikvorlieben und um Pro & Contra Open Source.
In den Kurzmeldungen: die Beta 2 von Visual Studio 2010 und .NET 4.0, der erste Geburtstag von Small Basic, Neues zur Microsoft Press Preview, die Online-Trainings der Weiterbildungsinitiative LiftOff und die integrierte Entwicklungsumgebung Eclipse zur Verbesserung der Interoperabilität von Windows 7, Windows Azure und Silverlight.

Ausserdem gibt es am Ende der msdn tv-Folge noch die Gewinnmöglichkeit für eine von 5 Expression Studio 3 Lizenzen. Einfach diesen Text twittern (@jansche RTen und Expression Studio gewinnen! msdn tv - Nachrichten für Entwickler http://msdn-online.de/msdntv #msdntv) um automatisch an der Verlosung teilzunehmen. Die Gewinnspielbedingungen findet ihr hier: http://www.der-evangelist.de/rechtliches/expression-studio-gewinnspiel-teilnahmebedingungen/

Die Gewinner werden schriftlich über eine DirectMessage (bei Teilnahme über twitter.com) oder per Post (bei Einsendung einer Postkarte, Absender nicht vergessen!) benachrichtigt.

Viel Glück und Viel Spass,
Der Jan mit dem Hut

Making of Community-Projects – Interview mit Norbert Eder

06.11.2009 08:34:45 | Norbert Eder

Gregor Biswanger hat mich vor einigen Tagen zum Thema Making of Community-Projects interviewt. Dabei ist ein nettes Gespräch entstanden, welches seit gestern bei ihm zu lesen ist. Es stand die Frage im Raum, wie es denn zu Community-Projekten kommt und wie man denn diese schließlich aufbaut. Ein nettes Gespräch, wo es wohl noch massig weitere...

Exam 70-564: Designing and Developing Applications using the Microsoft .NET Framework 3.5

05.11.2009 19:17:00 | Martin Hey

Nach 3 Monaten war nun mal wieder eine Zertifizierungsprüfung dran - diesmal war es die Nummer 70-564. Das Ergebnis ist "Passed" sobald die Systeme von Microsoft aktualisiert sind darf ich mich "Microsoft Certified Professional Developer - ASP.NET Developer 3.5" nennen.

Umfang der Prüfung waren 50 Fragen aus folgenden Themengebieten:
  • Designing and Implementing Controls
  • Designing the Presentation and Layout of an Application
  • Accessing Data and Services
  • Establishing ASP.NET Solution Structure
  • Leveraging and Extending ASP.NET Architecture
  • Applying Security Principles in Application Design
Mit dabei waren Fragen, nach dem Motto "Welches Ergebnis liefert diese LINQ-Query?", "Welche DataAdapter werden wann verwendet?", "Welche datengebunden Controls haben welche spezifischen Eigenschaften?" oder "Welche Anwendungsarchitektur wählt man wenn eine Firewall mit gewissen Eigenschaften im Netz exisitiert?"

Mein Eindruck war, dass die Fragen sehr nah an die der MCTS-Prüfung 70-562 angelehnt sind und jemand der diese Prüfung bestanden hat und im täglichen Geschäft ASP.NET-Anwendungen entwickelt auch die PRO-Prüfung bestehen kann.

Wordconv.exe liefert Exitcode=-14

05.11.2009 18:19:00 | Jan Christian Selke

Ist die Lösung für alles doch nicht 42? Oder was bedeutet der ExitCode=-14 der Wordconv.exe?

Vor einiger Zeit haben wir einen Windows Service zur automatischen Konvertierung von Word 2000 und 2003 Dokumenten in das neue Office OpenXml Format geschrieben. Dieser Service basiert auf dem Microsoft Office Compatibility Pack for Word, Excel, and PowerPoint 2007 File Formats von Microsoft, genauer gesagt auf der darin enthaltenen wordconv.exe. Konkret wird ein Prozessstart mit Aufruf der wordconv.exe gekapselt.

Nachdem dieser Service nun schon seit geraumer Zeit ohne großes Murren seine Dienste verrichtete, strich er einfach seine Segel. Alles was ihm noch zu entlocken war, war der Exitcode=-14. Allerdings schien die Arbeitsverweigerung eingangs willkürlich stattzufinden. Nach eingehender Analyse war zumindest festzustellen, dass es immer wieder die gleichen Dokumente waren, die diesen Zustand hervorriefen. Über “Save as…”, das AddIn innerhalb des Kontextmenüs im Explorer, ließen sich diese Dokumente aber scheinbar erfolgreich konvertieren.

Aus reiner Angewohnheit und purer Verzweiflung habe ich eine der Dateien von .doc in .zip umbenannt… zu meiner Verwunderung ließ sie sich auch noch Öffnen! Siehe da, es waren gar keine Dateien im Word 97-2003 Format, sondern falsch benannte .docx Dateien. Verwundert hat mich letztendlich das unterschiedliche Verhalten der wordconv.exe zu dem Kontextmenü Aufruf des Konverters. Nach weiteren Tests mit verschiedenen Dateiformaten scheint sich bestätigt zu haben, dass der Code –14 nur für die versuchte Konvertierung von docx Dokumenten gilt.

TFS Kompatibilität mit älteren VS Clients

05.11.2009 17:20:27 | Christian Binder

Da diese Frage nun schon öfters bekommen habe, hier der Stand der Dinge:
Ja man kann mit VS 2005 und 2008 auf TFS 2010 zugreifen, womit der Umstieg auf TFS 2010 deutlich vereinfacht wird. Was geht und Was nicht ist hier genau beschrieben. Dennoch muss noch folgender Patch auf den Clients installiert werden:
Visual Studio Team System 2008 Service Pack 1 Forward Compatibility Update for Team Foundation Server 2010

Chris

Microsoft Hotline - Hilfe, Support, Problem-Loesung, Kontakt, Telefon

05.11.2009 11:04:20 | Kay Giza

Häufig werde ich gefragt, wie man am besten bzw. schnellsten Kontakt zu Microsoft aufnimmt. Sei es per E-Mail, Telefon, Fax oder auch per Postbrief.
Es gibt viele verschiedene Wege, insbesondere wenn man z.B. Microsoft Partner ist, stehen einem weitere Wege offen oder wenn man z.B. Produkte erworben hat (wie z.B. eine MSDN Subscription).
Daher möchte ich hier nicht eine vollständige Liste veröffentlichen, sondern die wichtigsten Startpunkte.

Sollte Ihnen dieser Blogeintrag geholfen haben, so lassen Sie es mich doch bitte wissen.
Wenn Sie etwas anderes gesucht haben oder trotz dieser Hinweise nicht den richtigen Support gefunden haben, so lassen Sie es mich bitte auch wissen, ich versuche dann diese Liste zu vervollständigen.

Hilfe & Support Portal von Microsoft
Im Hilfe und Support-Portal von Microsoft finden Sie umfassende Informationen zu allen verfügbaren Produkten, bekommen Hinweise auf aktuellste Downloads und Update, erfahren wichtige Neuigkeiten und Infos.
Auf dieser Seite werden Sie entsprechend angeleitet, den richtigen Problemlösungsservice zu finden.

Technische Anfragen
Wenn Sie technische Unterstützung für Microsoft Produkte jeglicher Art benötigen, sei es durch ein aufgetretenes Problem, Sie haben einen sogenannten Bug entdeckt, benötigen technische Anleitung etc., dann sind Sie auf dieser Seite richtig. Wählen Sie auf der Liste das betroffene Produkt aus. Hier finden Sie alle unterstützten Produkte, wie Windows, Office, Visual Studio und viele mehr.

Kontakt zu Microsoft via Telefon Hotline, E-Mail, Fax oder Brief
Sollten Sie über die oben genannten Informationen nicht die richtige Kontaktstelle gefunden haben, so empfiehlt sich der direkte Kontakt zu Microsoft.
Auf dieser Seite finden Sie neben einer Telefonnummer, der Postanschrift etc., auch Hinweise, wie Sie online die richige technische Anfrage geben oder Sie finden die Möglichkeit, direkt einfach nur ein allgemeines Feedback Microsoft mitzuteilen.

Für Entwickler, Softwareentwickler jeglicher Art, Software-Architekten oder ISVs (Softwarehersteller) sowie MSDN Online-Kunden oder MSDN Subscription Kunden
Auf http://www.msdn-support.de finden Sie alle Hilfe & Support-Angebote für alle Teilnehmer des Microsoft Developer Network (MSDN) komprimiert und zusammengefasst. Weiterhin empfehle ich dazu meinen Blogeintrag 'Hilfe & Support' zu lesen.

Wie oben erwähnt, dies ist keine vollständige Auflistung, es soll helfen die ersten und wichtigsten Anlaufpunkte zu finden.

Tipp: Sollten Sie sich unsicher sein, welcher Support Ihnen zusteht, welchen Support Sie ggf. kontaktieren sollten, so empfehle ich Ihnen sich direkt per Telefon an Microsoft zu wenden und sich entsprechend beraten zu lassen.

Weiterführende Links als Stichwörter gelistet:

 



This post is powered by www.Giza-Blog.de | Giza-Blog.de: RSS Feed
Visit:  MSDN Online | Follow MSDN Online on Twitter | Follow Kay Giza on Twitter
Daily News on MSDN:  MSDN Aktuell
© Copyright 2006-2010 Kay Giza. All rights reserved. Legal
Subscribe

AzureNow gibt jetzt richtig Gas – Gewinnspiel verlängert!

05.11.2009 10:57:01 | Peter Kirchner

Eine erfreuliche Nachricht, das Gewinnspiel rund um Windows Azure, bei dem man ein Visual Studio 2010 gewinnen kann, wurde verlängert!

Hier nochmal alle Details zum Nachlesen:
Microsoft verlost zum Start von Windows Azure 100 brandneue Visual Studio Professional 2010 (verfügbar ab dem 2. Quartal 2010). Verlosungsteilnehmer müssen nicht mehr tun, als eine eigene Windows Azure Demo-Domäne einzurichten und dort eine Cloud Computing-Anwendung online zu stellen - die sie nicht mal selber entwickeln müssen. Warum machen wir's Ihnen so einfach? Weil Cloud Computing mit Windows Azure eben so einfach ist. Wie's geht, zeigt Ihnen MSDN-Experte Dariusz Parys im AzureNow How-To-Guide und dessen Video-Tutorials. Und damit Sie die „Cloud-Technologie“ von Microsoft richtig ausgiebig über die ruhigen Winterfeiertage testen und kennenlernen können, haben wir uns entschieden das Gewinnspiel zu verlängern. Weiterhin möchten wir so allen Gewinnspiel-Teilnehmern, die auf Grund des erfreulichen hohen Andrangs nicht sofort bei der Vergabe des Windows Azure-Token bedacht wurden, die Möglichkeit geben, Ihre Gewinnchancen zu wahren.

Ab sofort gilt also ein neuer Einsendeschluss: Donnerstag, 31.12.2009 24:00 Uhr. Ganz nach unserem Motto: „Cloud Computing – it’s so easy“ lernen Sie in 15 Minuten das Thema „Cloud Computing“ kennen und können auch noch ein Visual Studio 2010 gewinnen! Wenn das nicht mal schon ein vorgezogenes Weihnachtsgeschenk ist!


Alle Details, weiterführende Tutorials und Informationen zum Gewinnspiel finden Sie hier: AzureNow gibt jetzt richtig Gas – Gewinnspiel verlängert!

PowerShell: Batch-Umbennennen von Dateien

05.11.2009 09:54:00 | Martin Hey

Vom Übersetzer bekam ich für ein Projekt Sprachressourcen für die Benutzeroberfläche geliefert - allerdings hatte dieser nicht nur den Inhalt geändert, sondern auch in jedem Dateinamen vor der Erweiterung das Sprachkürzel eingefügt. Um wieder die originalen Dateinamen zu erhalten - also z.B. aus Form1it.xml wieder Form1.xml - hätte ich also jeden dieser Dateinamen editieren müssen. Und genau für solche einfachen Jobs eignet sich PowerShell recht gut.

get-childitem -Path *.* | rename-item -newName {$_.name -replace "it.xml", ".xml"}

Mit einer geschickten Kombination aus get-childitem und rename-item per Pipe konnte das Problem schnell gelöst werden.

Making of Community-Projects – Interview mit Norbert Eder

05.11.2009 09:11:28 | Gregor Biswanger

Inspiriert von Golo Roden´s “.NET Professionals im Profil” werden mit Making of Community-Projects die Macher von bekannten Community-Sites interviewt und mal von der persönlichen Seite durchleuchtet. Das Making of Community-Projects unterscheidet sich von .NET Professionals grundlegend, das es um die Projekte von Personen aus der Community geht und nicht um Professionale Softwareentwickler. Dabei wird gerade auf den täglichen Kampf der Community-People eingegangen und woher die Motivation für Neues gefunden wird.

 

foto_norbert

Norbert Eder

Beim spontanen Überlegen wer die meisten Community-Projekte in der .NET-Szene hat, fällt mir sofort Norbert Eder ein. Norbert Eder ist 32 Jahre alt und kommt aus Graz (Österreich). Ich konnte Norbert Eder für ein Interview gewinnen und bin schon gespannt was so alles  hinter den Projektfassaden steckt.

 

Gregor Biswanger: Hallo Norbert, erst mal vielen Dank das du dir die Zeit für ein Interview genommen hast. Ich muss gestehen, dass du mir das erste Mal auf Tutorials.de aufgefallen bist. Viele Fragen, die mich beschäftigt haben, führte Google direkt zu deinen Posts. Wie kam es damals zu deinem ersten Projekt? Was hat dich motiviert?

Norbert Eder: Ja, tutorials.de. Eine wunderbare Community, für die ich heute leider viel zu wenig Zeit habe. Hauptgrund hierfür sind wohl die persönlichen Präferenzen, die sich in den letzten Jahren doch stark verändert haben. Natürlich wollte ich auch weiterhin der Community behilflich sein, immerhin hatte auch ich viel Unterstützung erhalten. Die eigenen Communities (wobei eigentlich nur eines meiner aktuellen Projekte diesen „Titel“ verdient) haben sich nebenbei entwickelt. Das hat 2003 mit einem eigenen Blog angefangen und hat sich dann weiter entwickelt. Irgendwann gab es dann schon mal ein Forum, das sich hauptsächlich mit der Entwicklung für mobile Endgeräte beschäftigt, war aber wohl zu früh dafür. Einige Jahre später hatte ich dann Kai Gloth kennengelernt und daraus sind dann Projekte wie die .NET Casts oder das .NET BlogBook entstanden. Voriges Jahr dann eben .NET GUI, eine Plattform, auf der sich .NET Entwickler über User-Interface-Entwicklung auf Basis .NET austauschen können.

Die Motivation, die genannten Seiten (als auch noch weitere) zu betreiben ist damit zu begründen, dass ich insgesamt die .NET Community unterstützen und stärken möchte, verbunden mit einem gewissen Grad an Eigennutzen. So lernt man doch sehr viele unterschiedliche Menschen kennen, knüpft Kontakte. Das ist insgesamt schon sehr hilfreich.

 

Gregor Biswanger: Welches deiner ganzen Projekte ist dein persönlicher Favorit? Und warum?

Norbert Eder: Ich habe keinen persönlichen Favoriten. In den letzten Jahren fokussiere ich mich auf die Windows Presentation Foundation und auf Silverlight, da ich diesen Technologien eine große Zukunft voraus sage. Daher ist es naheliegend, auch in diese Richtung tätig zu sein bzw. diesen Bereich zu fördern (siehe WPF-Blogger, oder aber auch .NET GUI).

 

Gregor Biswanger: Warum ausgerechnet WPF und Silverlight? Hierbei müssten Unternehmen doch so vieles erneut lernen?

 

Norbert Eder: WPF als auch Silverlight erfordern natürlich (wie alle neuen Technologien) ein Maß an Lernaufwand, das ist schon richtig. Auf der anderen Seite steht natürlich die Möglichkeit, eine vollkommen neue „Experience“ für eigene Anwendungen/Produkte zu schaffen, weg von den gewohnten grauen Oberflächen, hin zu einer höheren Benutzerfreundlichkeit. Angereichert durch die neuen Möglichkeiten, lassen sich ohne viel Aufwand Animationen und Effekte einbinden, die bis dato nur unter (sehr) hohem Implementierungsaufwand möglich gewesen wären.

Ich konnte in den letzten Monaten einige WPF-Projekte betreuen (sowohl kleinere Anwendungen, als auch im Bereich von ~900 Clients) und überall hat sich gezeigt, dass die Einstiegshürden groß sind. Es muss jede Menge Überzeugungsarbeit geleistet werden, um ein Unternehmen tatsächlich auf diesen Zug zu bringen. Schlussendlich gab es aber in allen Fällen eine große Überraschung – im positiven Sinne.

 

Gregor Biswanger: Wie weit würdest du die Reife von WPF und Silverlight jetzt sehen?

 

Norbert Eder: Schwer zu sagen wie es in 10 Jahren aussehen wird. Fakt ist, dass WPF und Silverlight quasi am Anfang stehen und es noch jede Menge zu tun gibt. Mit zunehmender Akzeptanz werden weitere Wünsche und somit auch Möglichkeiten dargelegt. Es wird also wohl noch eine ganze Weile dauern, bis es zu einer gänzlich neuen Technologie kommt.

 

Gregor Biswanger: Nun ein kleiner Blick in dein Privatleben.. Mich würde dein Familienstand interessieren?

 

Norbert Eder: Glücklich verheiratet.

 

Gregor Biswanger: Wie kommt deine Frau mit deinem Erfolg in der Community klar? Ist Sie stolz auf dich oder habt ihr Stress?

 

Norbert Eder: „Erfolg in der Community“ ist ein Terminus, der mir nicht 100%ig zusagt. Wie ist dieser definiert und wer bestimmt darüber? Sind PageViews aussagekräftig was die Qualität betrifft? Ich selbst kann und will nicht behaupten, in der Community Erfolg zu haben, das müssen andere tun. Mir macht es Spaß (manchmal auch weniger) und wie ich schon anklingen ließ, so ganz uneigennützig ist es dann ja auch nicht.

Wir sind natürlich stolz auf das, was der andere leistet und unterstützen uns gegenseitig. Würde es keine Unterstützung geben, wäre Vieles nicht möglich.

 

Gregor Biswanger: Was würdest du jemand empfehlen der eine Idee für ein Community-Projekt hat?

 

Norbert Eder: Tun, nicht reden!

 

Gregor Biswanger: Was war für dich aus der Community heraus das angenehmste Erlebnis? Und warum war es so besonders für dich?

 

Norbert Eder: Es hat in den letzten Jahren viele angenehme Erlebnisse gegeben, da möchte ich mich auf keines besonders festlegen. Für mich ist es immer ein Erlebnis, neue, interessante Menschen kennen zu lernen, interessante Diskussionen zu führen und daraus schlussendlich auch selbst zu lernen. Einige Male entstanden auch wirklich gute Freundschaften – das ist mit nichts aufzuwiegen.

 

Gregor Biswanger: Und was war eher das Unerträglichste aus der Community?

 

Norbert Eder: Etwas Unerträgliches ist noch nicht passiert, Unverständliches dafür schon.

 

Gregor Biswanger: Neben deinem Hauptberuf als Solution Architect in der Firma UPPER Network GmbH arbeitest du nebenbei an der Fachhochschule Campus02 Graz als Fachhochschullektor für Java, C# und WPF. Wissen die Studenten von deinen starken Community-Aktivitäten?

 

Norbert Eder: Ich hänge es nicht groß an die Glocke, da die Lehre keine Werbeveranstaltung für meine Person ist. Diejenigen, die sich stärker mit den Themen C# und WPF beschäftigen, besuchen dann schon das eine oder andere Mal mein Blog oder eine meiner anderen Webseiten, wodurch natürlich auch entsprechende Gespräche entstehen.

 

Gregor Biswanger: Wenn du von Microsoft einen Wunsch frei hättest, speziell für die Community, was würdest du dann beanspruchen?

 

Norbert Eder: Wünsche an Microsoft hätte ich viele, die ich hier gar nicht alle aufzählen kann. Speziell für die Community denke ich, dass Microsoft Deutschland gute Arbeit leistet. Da ich jedoch aus Österreich komme, würde ich mir auch in unserem Land mehr Aktivität diesbezüglich wünschen. Es bedarf mehr Community-Veranstaltungen und eine verbesserte Kommunikation. Natürlich liegt dieser Punkt zu einem Großteil auch an der Community selbst, entsprechende Unterstützung wäre aber sehr willkommen.

 

Gregor Biswanger: Deine Community-Projekte handeln alle im Microsoft Bereich. Was genau zieht dich so an Microsoft an?

 

Norbert Eder: Anziehen ist der falsche Ausdruck. Ich war jahrelang auf der Linux/Java-Schiene tätig und sehe im Vergleich, dass vieles auf den Microsoft-Plattformen einfacher erledigt werden kann und man sich als Entwickler um viele Bereiche nicht kümmern muss. Entwickler sind ja von Grund auf faule Menschen und da spielt das schon eine Rolle. Ich möchte mich auf die wirklich wichtigen Aufgaben konzentrieren und da möchte ich natürlich, dass mich die angrenzende Umgebung entsprechend unterstützt. Das sehe ich auf der Microsoft-Plattform als besser gelöst als auf anderen. Meine persönliche Entwicklung hätte also durchaus auch in eine andere Richtung gehen können. Zum jetzigen Zeitpunkt ist es dann logisch, sich intensiv mit seinen gewählten Bereichen zu beschäftigen, darf jedoch den Blick über den Tellerrand nicht vergessen. Das ist unter anderem auch einer der Gründe, warum ich Java unterrichte und mich beispielsweise mit Ruby beschäftige.

 

Gregor Biswanger: Was ist derzeit dein aktuelles Projekt? Was erhoffst du dir dabei?

 

Norbert Eder: Aktuell bereite ich mit Mario Meir-Huber gerade den .NET Open Space Vienna 2009 vor. Damit bringen wir diese Veranstaltung auch nach Österreich und hoffen, dass es auch bei uns viele Teilnehmer und angeregte Diskussionen geben wird. Sonst kümmere ich mich hauptsächlich um .NET GUI, habe aber auch noch ein paar neue Ideen für WPF Blogger in meiner Schublade. Aktuell hat allerdings mein WPF-Buch Vorrang, von dem ich mir erhoffe, dass es schlussendlich meine Erwartungen und die der Leser erfüllen wird.

Danach wird sich zeigen, wie es weitergeht. Grundsätzlich stehen schon noch ein paar Projektideen in meinem schlauen Büchlein, die auf Umsetzung warten.

 

Gregor Biswanger: Vielen Dank, Norbert, für dein Engagement! Auch ein großes Danke für die tollen Projekte von dir, die mir und allen anderen eine große Hilfe leisten.

 

Norbert Eder: Keine Ursache. Ich bedanke mich für das Interview.

Back from .NET Information Day in Darmstadt

05.11.2009 01:12:00 | Lars Keller

Ich bin gerade auf dem Rückweg vom .NET Information Day in Darmstadt. Es war eine gelungene Veranstaltung und es hat sehr viel Spaß gemacht. Wie versprochen gibt es hier meine Slides und mein Codebeispiel:

Slides: download

Code: ExcelImportEmails download

Es hat mich auch sehr gefreut, dass viele Studenten vor Ort waren und sich auch für die VSTO interessiert haben. Vielen Dank an die Organisatoren: Kostja, Teddy, Grisha und die vielen Helfer!

Beim nächsten .NET Information Day bin ich gerne wieder dabei!

Einfache Input-Validation mit WPF

04.11.2009 23:01:00 | Lars Schmitt

Auch in aktuellen Anwendungen passiert es leider immer wieder

  • nicht ausgefüllte Pflichtfelder
  • Textlänge zu kurz oder zu lang
  • es wurden ein Text anstatt einer Zahl eingegeben
  • PLZ, Email, Urls Fehlerhaft

 

Die Input-Validation ist also eine Thematik, die selbst in den kleinsten Anwendungen mit beachtet werden sollte, aus diesem Grund handelt das heutige Blog-post genau über diese Thematik.

 

Als Beispiel Applikation, nehme ich heute kleines ein Formular, um neue Kontakt Daten zu erfassen.

  

using System;   

namespace WpfApplication3    
{     
    public class Kontakt     
    {     
        public string Vorname { get; set; }     
        public string Nachnam { get; set; }     
        public string EMail { get; set; }     
        public string Tel { get; set; }     
        public string Street { get; set; }     
        public string Hausnummer { get; set; }     
        public string Plz { get; set; }     
        public string Ort { get; set; }     
    }     
}  

in dieser einfachen Datenstruktur, gibt es schon genug Stolpersteine, die eine Imput-Validation erfordern.

dazu noch ein einfaches aber funktionales Window

  

<Window x:Class="WpfApplication3.KontaktForm"    
        xmlns="<a href="http://schemas.microsoft.com/winfx/2006/xaml/presentation"">http://schemas.microsoft.com/winfx/2006/xaml/presentation"</a     
        xmlns:x="<a href=">http://schemas.microsoft.com/winfx/2006/xaml"">http://schemas.microsoft.com/winfx/2006/xaml"</a     
        Title="Kontakt" Height="350" Width="525">   

    <Grid>    
        <Grid.RowDefinitions>     
            <RowDefinition Height="Auto"/>     
            <RowDefinition Height="Auto"/>     
            <RowDefinition Height="Auto"/>     
            <RowDefinition Height="Auto"/>     
            <RowDefinition Height="10"/>     
            <RowDefinition Height="Auto"/>     
            <RowDefinition Height="Auto"/>     
        </Grid.RowDefinitions>     
        <Grid.ColumnDefinitions>     
            <ColumnDefinition Width="Auto"/>     
            <ColumnDefinition Width="3*"/>     
            <ColumnDefinition Width="3*"/>     
        </Grid.ColumnDefinitions>     
        <TextBlock Grid.Row="0" Grid.ColumnSpan="3" HorizontalAlignment="Center">Kontakte</TextBlock>        
        <Label Grid.Row="1" Grid.Column="0">Vorname/Nachname</Label>     
        <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Path=Vorname}" Margin="3"/>     
        <TextBox Grid.Row="1" Grid.Column="2" Text="{Binding Path=Nachname}" Margin="3"/>     
        <Label Grid.Row="2" Grid.Column="0">Straße/HausNr.</Label>     
        <TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Path=Strasse}" Margin="3"/>     
        <TextBox Grid.Row="2" Grid.Column="2" Text="{Binding Path=Hausnummer}" Margin="3"/>     
        <Label Grid.Row="3" Grid.Column="0">PLZ/Ort</Label>     
        <TextBox Grid.Row="3" Grid.Column="1" Text="{Binding Path=Plz}" Margin="3"/>     
        <TextBox Grid.Row="3" Grid.Column="2" Text="{Binding Path=Ort}" Margin="3"/>     
        <Label Grid.Row="5" Grid.Column="0">E-Mail</Label>     
        <TextBox Grid.Row="5" Grid.Column="1" Text="{Binding Path=EMail}" Margin="3"/>     
        <Label Grid.Row="6" Grid.Column="0">Tel</Label>     
        <TextBox Grid.Row="6" Grid.Column="1" Text="{Binding Path=Tel}" Margin="3"/>     
    </Grid>   

</Window>  

im jetzigen Zustand dieser Form, können an allen möglichen Stellen, falsche Daten eingegeben werden. (Und glaubt mir, Anwender machen das dann auch)

Was man an dieser Stelle braucht, wäre auf keinen Fall eine Methode wie zb

  

private bool CheckAllValues(){  

if  (!string.IsNullOrEmpty(source.Vorname)){  

       MessageBox.Show(“Fehler bei der Eingabe, das Feld Vorname ist ein Pflichtfeld! …”, “Fehler”);  

      return false;  

}  

…  

}  

die vor jedem speichern ausgeführt wird, und nur so mit MessageBoxen um sich schmeißt.

Viel besser wäre doch eine Überprüfung, nach der Eingabe des jeweiligen wertes, mit einer sofortigen Visualisierung.

 

Welche Änderungen, müssen dafür an dem Vorhanden Code vorgenommen werden.

 

Als erstes sollte die Datenstruktur, das Interface IDataErrorInfo Implementieren.

zusätzlich benutze ich ein private Dictionary, um nach einer Prüfung die Fehlermeldungen zu speichern.

  

using System;   
using System.ComponentModel;    
using System.Collections.Generic;    
using System.Text.RegularExpressions;   

namespace WpfApplication3   
{    
    public class Kontakt : IDataErrorInfo    
    {    
        Dictionary<string, string> errorDict;   

        public Kontakt()   
        {    
            errorDict = new Dictionary<string, string>();   

            InitErrorDict();   
        }   

        //mit Initial Meldungen beim kreieren vorbelegen   
        private void InitErrorDict()    
        {    
            //diese 3 Felder sind Pflichtfelder    
            errorDict.Add("Vorname", "Pflichtfeld");    
            errorDict.Add("Nachname", "Pflichtfeld");    
            errorDict.Add("EMail", "Pflichtfeld");    
        }    
        private string _vorname;    
        private string _nachname;    
        private string _eMail;    
        private string _tel;    
        private string _plz;    
        public string Vorname { get { return _vorname; } set { if (IsNullOrEmpty(value, "Vorname")) _vorname = value; } }    
        public string Nachname { get { return _nachname; } set { if (IsNullOrEmpty(value, "Nachname")) _nachname = value; } }    
        public string EMail { get { return _eMail; } set { if (IsNullOrEmpty(value, "EMail") && IsEMail(value, "EMail")) _eMail = value; } }    
        public string Tel { get { return _tel; } set { if (IsPhone(value, "Tel")) _tel = value; } }    
        public string Strasse { get; set; }    
        public string Hausnummer { get; set; }    
        public string Plz { get { return _plz; } set { if (IsPLZ(value, "Plz")) _plz = value; } }    
        public string Ort { get; set; }   

        private bool IsPhone(string value, string propertyName)   
        {    
            Regex regex = new Regex(@"^\(\d{1,2}(\s\d{1,2}){1,2}\)\s(\d{1,2}(\s\d{1,2}){1,2})((-(\d{1,4})){0,1})$");   

            if (!regex.IsMatch(value))   
            {    
                errorDict.Add(propertyName, "Dies ist keine Telefonnummer!");    
                return false;    
            }    
            else    
                return true;    
        }    
        private bool IsPLZ(string value, string propertyName)    
        {    
            Regex regex = new Regex(@"^\d{5}$");   

            if (!regex.IsMatch(value))   
            {    
                errorDict.Add(propertyName, "Dies ist keine Postleitzahl!");    
                return false;    
            }    
            else    
                return true;    
        }   

        private bool IsEMail(string value, string propertyName)   
        {    
            Regex regex = new Regex(@"^[-_.\w]+@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.){1,300}([a-zA-Z]{2,9})$");   

            if (!regex.IsMatch(value))   
            {    
                errorDict.Add(propertyName, "Dies ist keine EMail Adresse!");    
                return false;    
            }    
            else    
                return true;    
        }   

        private bool IsNullOrEmpty(string value, string propertyName)   
        {    
            if (string.IsNullOrEmpty(value))    
            {    
                errorDict.Add(propertyName, "Dies ist ein Pflichtfeld!");    
                return false;    
            }    
            else    
                return true;    
        }   

        public string Error   
        {    
            get { throw new NotImplementedException(); }    
        }   

        public string this[string columnName]   
        {    
            get    
            {    
                if (errorDict.ContainsKey(columnName))    
                    return errorDict[columnName];    
                else    
                    return "";    
            }    
        }    
    }    
}  

  

 

Was jetzt noch zu tun wäre, ist die Anpassung der Oberfläche.

zur Visualisierung der Fehler dient, an dieser Stelle das ErrorTemplate, denn sobald die darunterliegende Datenklasse meldet, dass ein Fehler für ein bestimmtes Feld vorhanden ist wird dieses ErrorTemplate benutzt und Visualisiert dem Anwender somit sofort das ein Fehler vorliegt.


Wichtig für diese Art der Validation ist das Property ValidatesOnDataErrors, dass für die entsprechenden Felder auf wahr gesetzt werden muss und die Implementierung der Interfaces.


  

<Window x:Class="WpfApplication3.KontaktForm"   
        xmlns="<a href="http://schemas.microsoft.com/winfx/2006/xaml/presentation"">http://schemas.microsoft.com/winfx/2006/xaml/presentation"</a    
        xmlns:x="<a href=">http://schemas.microsoft.com/winfx/2006/xaml"">http://schemas.microsoft.com/winfx/2006/xaml"</a    
        Title="Kontakt" Height="350" Width="525">   

    <Window.Resources>   
        <ControlTemplate x:Key="ErrorTemplate">    
            <DockPanel>    
                <Grid DockPanel.Dock="Left" Margin="0,0,2,0">    
                    <Ellipse Width="17" Height="17" Fill="Yellow"/>    
                    <TextBlock Text="!" FontWeight="Bold" HorizontalAlignment="Center" VerticalAlignment="Center"/>    
                </Grid>    
                <Border DockPanel.Dock="Right" BorderBrush="Red" BorderThickness="1">    
                    <AdornedElementPlaceholder />    
                </Border>    
            </DockPanel>    
        </ControlTemplate>   

        <Style TargetType="{x:Type TextBox}">   
            <Setter Property="Validation.ErrorTemplate" Value="{StaticResource ErrorTemplate}"/>    
            <Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}"/>   

        </Style>   
    </Window.Resources>   

    <DockPanel>   
        <StatusBar DockPanel.Dock="Bottom">    
            <StatusBarItem Content="{Binding Path=Error}"/>    
        </StatusBar>    
        <Grid>    
            <Grid.RowDefinitions>    
                <RowDefinition Height="Auto"/>    
                <RowDefinition Height="Auto"/>    
                <RowDefinition Height="Auto"/>    
                <RowDefinition Height="Auto"/>    
                <RowDefinition Height="10"/>    
                <RowDefinition Height="Auto"/>    
                <RowDefinition Height="Auto"/>    
            </Grid.RowDefinitions>    
            <Grid.ColumnDefinitions>    
                <ColumnDefinition Width="Auto"/>    
                <ColumnDefinition Width="3*"/>    
                <ColumnDefinition Width="3*"/>    
            </Grid.ColumnDefinitions>    
            <TextBlock Grid.Row="0" Grid.ColumnSpan="3" HorizontalAlignment="Center" >Kontakte</TextBlock>    
            <Label Grid.Row="1" Grid.Column="0">Vorname/Nachname</Label>    
            <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Path=Vorname, ValidatesOnDataErrors=true}" Margin="5"/>    
            <TextBox Grid.Row="1" Grid.Column="2" Text="{Binding Path=Nachname, ValidatesOnDataErrors=true}" Margin="5"/>    
            <Label Grid.Row="2" Grid.Column="0">Straße/HausNr.</Label>    
            <TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Path=Strasse, ValidatesOnDataErrors=true}" Margin="5"/>    
            <TextBox Grid.Row="2" Grid.Column="2" Text="{Binding Path=Hausnummer, ValidatesOnDataErrors=true}" Margin="5"/>    
            <Label Grid.Row="3" Grid.Column="0">PLZ/Ort</Label>    
            <TextBox Grid.Row="3" Grid.Column="1" Text="{Binding Path=Plz, ValidatesOnDataErrors=true}" Margin="5"/>    
            <TextBox Grid.Row="3" Grid.Column="2" Text="{Binding Path=Ort, ValidatesOnDataErrors=true}" Margin="5"/>    
            <Label Grid.Row="5" Grid.Column="0">E-Mail</Label>    
            <TextBox Grid.Row="5" Grid.Column="1" Text="{Binding Path=EMail, ValidatesOnDataErrors=true}" Margin="5"/>    
            <Label Grid.Row="6" Grid.Column="0">Tel</Label>    
            <TextBox Grid.Row="6" Grid.Column="1" Text="{Binding Path=Tel, ValidatesOnDataErrors=true}" Margin="5"/>    
        </Grid>    
    </DockPanel>    
</Window>  

 

Und abschließend wieder mal eine kleine Grafik!!

 

Validate

 

Und bevor Ihr es mir Mitteilen wollte, ich weiß das dies nicht die einzigsten Möglichkeiten sind.


Anregungen, Ideen, Fragen, … immer her damit, entweder als Kommentar oder übers Kontaktformular.

Merge Documents: Dokumente zusammenführen mit Übernahme von Bildern

04.11.2009 20:47:00 | Jan Christian Selke

Nach einiger Zeit der theoretischen Auseinandersetzung mit dem OpenXml SDK 2 habe ich mich entschlossen etwas ”Butter bei die Fische” zu geben. Nach und nach werde ich mich von jetzt an mit verschiedenen Aspekten der Dokumenterstellung beschäftigen.
Ein erstes konkretes Thema ist nun das Zusammenfügen von zwei Dokumenten mit Bildinhalt. Container des Zieldokuments bildet ein Content Control, das über seinen Tag identifiziert werden soll. Die Antwort auf die Frage, wie dies mit OpenXml SDK 1.0 realisiert werden kann, ist so einfach wie kurz; Mit XPath und direkter Xml Bearbeitung. Dies ist durch die typisierten Klassen des OpenXml SDK 2.0 mittlerweile nicht mehr notwendig. Nach kurzer Suche habe ich keine für mich zufriedenstellende Lösung gefunden, es existieren aber ein Vielzahl an Lösungen mit XDocument, XElement und LINQ To XML. Da selber machen auch ohnehin mehr Spaß macht, habe ich einen möglichen Ansatz verfolgt, wie ich mir eine Umsetzung mit den SDK Klassen vorstellen könnte.
Hierfür habe ich zwei einfache Dokumente erstellt. Ein Dokument mit Titelzeile und Bild, dessen Inhalt kopiert werden soll
 image
und ein Dokument, das als Container den Inhalt des ersten Dokuments in das bereits erwähnte Content Control aufnehmen soll.
 image
Die Eigenschaften des Content Controls müssen entsprechend angepasst werden, wenn es für die Aufnahme des einzufügenden Dokuments eindeutig identifiziert werden soll. Für den Tag wird der Wert “100” eingetragen und der Titel wird mit “Logo” befüllt. Der Titel ist für den weiteren Ablauf nicht relevant und könnte daher auch weggelassen werden.
 image
Bevor es unmittelbar an die Entwicklung geht, werfen wir einen Blick auf das Markup der Dokumente. Das Zieldokument beinhaltet einen Absatz <w:p> mit dem Text “Logo:” oberhalb des Content Controls, welches durch das Tag <w:sdt> repräsentiert wird. Bei dem Steuerelement handelt es sich um ein Block-Level Element. Block-Level Elemente können im Gegensatz zu Inline-Level Elementen mehrere Zeilen umfassen. Sie sind dadurch gekennzeichnet, dass im Content Bereich <w:sdtContent>, dem sichtbaren Inhaltsbereich eines Content Controls,  Paragraphen <w:p> Tags als Child Elemente aufgenommen werden dürfen, was in der erwähnten Mehrzeiligkeit resultiert. Der Content besteht nur aus dem Text “Hier kommt der Text rein”. In den Eigenschaften des Content Controls, repräsentiert durch <w:sdtPr>, ist unter anderem der eben eingegebene Alias <w:alias> sowie das Tag <w:tag> hinterlegt. Zusätzlich noch eine ID <w:id> die dokumentweit eindeutig ist, sowie der Platzhaltertext <w:placeholder>, der wasserzeichenartig angezeigt wird, wenn kein Text enthalten ist.
Beendet wird das Dokument von der MainSection <w:sectPr>, die als letztes Element direkt im Body hinterlegt ist. Sie ist der Standardwert, der innerhalb des Dokument genutzt wird. Hier werden beispielsweise die Kopf- und Fußzeilen Referenzen, Orientierung oder die Seitenränder hinterlegt.
image
Das einzufügende Dokument beinhaltet nur einen Paragraphen. In diesem Paragraphen sind der Bildtitel und das Bild enthalten. Die Einbettung einer Graphik in ein Dokument erfolgt als <w:drawing> Element. Sie werden innerhalb eines Text-Runs <w:r> eingefügt und können entweder vom Typ <wp:inline>  - in der Zeile mit dem Text des Paragraphen und damit ebenso verschiebbar -  oder <wp:anchor> – mit fester Positionsangabe auf der Seite verankert - sein. Das Element <a:graphic> spezifiziert das Vorhandensein eines Graphikelements, das durch <a:graphicData> konkretisiert wird. Auffällig ist die explizit angegebene Uri. Diese ist notwendig, da durch Angabe der Uri der Typ der Graphik ermittelt wird. Folgende Graphiktypen können angegeben werden:
Namespace
Tag
http://schemas.openxmlformats.org/drawingml/2006/table
tbl
http://schemas.openxmlformats.org/drawingml/2006/diagram
relIds
http://schemas.openxmlformats.org/drawingml/2006/chart
chart
http://schemas.openxmlformats.org/drawingml/2006/picture
pic
http://schemas.openxmlformats.org/drawingml/2006/compatibility
legacyDrawing
http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas
lockedCanvas
http://schemas.openxmlformats.org/presentationml/2006/ole
oleObj
Quelle: MSDN Forum

Noch zu erwähnen ist das <a:blip> Element, genauer das r:embed Attribut. Blip steht für Binary Large Image or Picture. Das Attribut r:embed impliziert, dass das Bild als eingebettetes Element in Form eines ImageParts innerhalb der Datei vorliegt. Das Attribut r:link verweist auf eine extern referenzierte Bilddatei im Dateisystem.
image
Aber nun zum spannenden  Teil – der Entwicklung. Zuerst ein paar grundlegende Gedanken zum Ablauf dessen, was passieren soll. Analog der zwei beschriebenen Dokumente benötigen wir auch zwei Objekte vom Typ WordprocessingDocument. Beide Dokumente müssen geöffnet, das Content Control gefunden und dann der Inhalt kopiert werden. Nach Kopieren des Inhalts muss ein abgleich der Bilddaten stattfinden. Zum Abschluss wird der neue Mainpart gespeichert.
In Codeform habe ich alles in einer Methode ImportDokument zusammen gefasst.
public void ImportDocument(string inputFile, string mergableFile)
{
    using (var inputDocument = WordprocessingDocument.Open(mergableFile, false))
    {
        using (var outputDocument = WordprocessingDocument.Open(inputFile, true))
        {
            MainDocumentPart inputMainDocumentPart = inputDocument.MainDocumentPart;
            MainDocumentPart outputMainDocumentPart = outputDocument.MainDocumentPart;

            SdtBlock importSdtBlock = PrepareImportSdtBlock(outputMainDocumentPart);
            CopyContent(importSdtBlock, inputMainDocumentPart, true);
            SyncPictures(importSdtBlock, outputMainDocumentPart,  inputMainDocumentPart);
            outputMainDocumentPart.Document.Save(outputMainDocumentPart);
        }
    }
}

Die Methode PrepareImportSdtBlock muss nicht weiter erklärt werden. Das Content Control wird identifiziert und der aktuelle Inhalt gelöscht. Inhaltlich interessanter ist die Methode CopyContent. Sehen wir uns an, wie der Inhalt kopiert wird.
private static void CopyContent(SdtBlock block, MainDocumentPart inputMainDocumentPart, bool keepMainSection)
{
    foreach (var child in inputMainDocumentPart.Document.Body.ChildElements)
    {
        if (child is SectionProperties)
        {
            if (keepMainSection)
            {
                block.SdtContentBlock.AppendChild(new Paragraph(new ParagraphProperties(child.CloneNode(true))));
            }
        }

        block.SdtContentBlock.Append(child.CloneNode(true));
    }
}

Es wird durch alle Child Elemente des Bodys, also alle unmittelbar dem <w:body> Element untergeordneten Elemente iteriert und in das Content Control kopiert. Hierzu wird die Methode CloneNode aufgerufen. CloneNode erzeugt eine Kopie des Elements und aller Subelemente. Mit keepMainSection wurde ein Flag eingeführt, das signalisiert, ob die MainSection nach der Übernahme erhalten bleiben soll.  Soll diese erhalten bleiben, wird ein neuer umschließender Paragraph erzeugt, andernfalls wird sie ersatzlos gelöscht. Nicht unerwähnt bleiben soll, dass hiermit verschiedene Implikationen verbunden sind. Bleibt die MainSection erhalten und es wird ein neuer Paragraph erzeugt, erscheint dieser natürlich auch im Dokument. Wird sie nicht erhalten, kann es vorkommen, dass der letzte Abschnittswechsel des neu eingefügten Textes falsch dargestellt wird. Hier kann Bedarf bestehen, sich intensiver mit Formatierungen auseinander zu setzen.
Im Anschluss findet eine Synchronisation der Bilddaten zwischen den Dokumenten statt. Übergeben wird das Content Control, dass nun bereits die importierten Daten enthält, sowie die Mainparts des Ausgangs- und Zieldokuments.
private void SyncPictures(SdtBlock containerSdtBlock, MainDocumentPart outputMainDocumentPart, MainDocumentPart inputMainDocumentPart)
{
    foreach (Picture pic in containerSdtBlock.Descendants<Picture>())
    {
        Blip blip = pic.BlipFill.Blip;
        ImagePart oldPart = (ImagePart)inputMainDocumentPart.GetPartById(blip.Embed.Value);
        if (oldPart != null)
        {
            ImportImagePart(blip, oldPart, outputMainDocumentPart);
        }
    }
}

Für jedes importierte, im Content Control gefundene Bild – ein Bild entspricht der Klasse Picture – wird über das Attribut Embed der Blip Klasse, der ImagePart des Ausgangsdokuments identifiziert, der die Daten enthält. Per Link referenzierte Bilder werden nicht beachtet. Existiert im Ausgangsdokument ein entsprechender ImagePart, so wird dieser in das Zieldokument importiert.
private void ImportImagePart(Blip blip, ImagePart oldPart, MainDocumentPart outputMainDocumentPart)
{
    ImagePart newImagePart = outputMainDocumentPart.AddImagePart(oldPart.ContentType);
    CopyPartContent(oldPart, newImagePart);
    blip.Embed.Value = outputMainDocumentPart.GetIdOfPart(newImagePart);
}

Innerhalb des Zieldokuments wird über AddImagePart ein neuer ImagePart vom ContentType des alten Parts (oldPart.ContentType) angelegt. Bei dem ContentType handelt es sich um den MIME Type der Daten eines ImageParts. Der Inhalt des Parts wird in einen Stream ausgelesen und in den neuen Part geschrieben. Im Anschluss wird die Id des neuen ImageParts als neuer Wert des Embed Attributs des importierten Bildes geschrieben.
private void CopyPartContent<T>(T oldPart, T newPart) where T : OpenXmlPart
{
    using (Stream inputStream = oldPart.GetStream(FileMode.Open, FileAccess.Read))
    {
        byte[] oldPartContent = new byte[inputStream.Length];
        inputStream.Read(oldPartContent, 0, (int)inputStream.Length);
        using (Stream outputStream = newPart.GetStream(FileMode.Open, FileAccess.ReadWrite))
        {
            outputStream.Write(oldPartContent, 0, oldPartContent.Length);
        }
    }
}

Das Kopieren des Inhalts von Parts ist bewusst generisch gehalten, da diese Funktionalität in gleicher Weise auch für das Kopieren anderer Parts genutzt werden kann. In dieser Form können alle Parts kopiert werden, die von der Basisklasse OpenXmlPart erben.
Ist nun der Aufruf einmal vollständig durchgelaufen, sollte das Zieldokument vollständig um das einzufügende erweitert worden sein. Ein Blick in das Markup zeigt, dass der Inhalt des Bodys tatsächlich vollständig in das Content Control übertragen wurde.
image
Öffnet man das Dokument, wird der Inhalt mit Bild auch innerhalb des Content Controls angezeigt. Das Ergebnis sollte dann entsprechend des folgenden Screenshots aussehen.
image
Fazit
Schwächen sind in diesem Test noch vorhanden, die vor allem auf die Vielschichtigkeit und Weitläufigkeit der zu berücksichtigenden Aspekte und Seiteneffekte hindeuten. Es können noch mehrfach identische Bilder importiert werden. Es findet keine Prüfung statt, ob ein Bild etwa bereits als ImagePart im Zieldokument existiert. Es muss geprüft werden, wie eine entsprechende Identifikation bereits vorhandener identischer Bildinhalte aussehen kann. Extern referenzierte und nicht eingebettete Bilder werden nicht kopiert. Zur Zeit bleibt das Content Control erhalten, was berechtigterweise aus Sicht der Ästhetik als verbesserungsfähig  angesehen werden kann. Bei Bedarf kann das Content Control gelöscht und durch den reinen Inhalt ersetzt werden.
Das komplette Entwicklungsprojekt befindet sich zum Download hier.

AzureNow gibt jetzt richtig Gas – Gewinnspiel verlaengert!

04.11.2009 19:02:08 | Kay Giza

Eine erfreuliche Nachricht, das Gewinnspiel rund um Windows Azure, bei dem man ein Visual Studio 2010 gewinnen kann, wurde verlängert!

Hier nochmal alle Details:
Microsoft verlost zum Start von Windows Azure 100 brandneue Visual Studio Professional 2010 (verfügbar ab dem 2. Quartal 2010). Verlosungsteilnehmer müssen nicht mehr tun, als eine eigene Windows Azure Demo-Domäne einzurichten und dort eine Cloud Computing-Anwendung online zu stellen - die sie nicht mal selber entwickeln müssen. Warum machen wir's Ihnen so einfach? Weil Cloud Computing mit Windows Azure eben so einfach ist. Wie's geht, zeigt Ihnen MSDN-Experte Dariusz Parys im AzureNow How-To-Guide und dessen Video-Tutorials. Und damit Sie die „Cloud-Technologie“ von Microsoft richtig ausgiebig über die ruhigen Winterfeiertage testen und kennenlernen können, haben wir uns entschieden das Gewinnspiel zu verlängern. Weiterhin möchten wir so allen Gewinnspiel-Teilnehmern, die auf Grund des erfreulichen hohen Andrangs nicht sofort bei der Vergabe des Windows Azure-Token bedacht wurden, die Möglichkeit geben, Ihre Gewinnchancen zu wahren. Ab sofort gilt also ein neuer Einsendeschluss: Donnerstag, 31.12.2009 24:00 Uhr. Ganz nach unserem Motto: „Cloud Computing – it’s so easy“ lernen Sie in 15 Minuten das Thema „Cloud Computing“ kennen und können auch noch ein Visual Studio 2010 gewinnen!
Wenn das nicht mal schon ein vorgezogenes Weihnachtsgeschenk ist ;-)!


Alle Details, weiterführende Tutorials und Informationen zum Gewinnspiel finden Sie hier:  AzureNow gibt jetzt richtig Gas – Gewinnspiel verlängert!
Windows Azure: Jetzt kostenlos testen & 100 Visual Studio 2010 gewinnen!
Ich wünsche viel Glück und Erfolg! :)



This post is powered by www.Giza-Blog.de | Giza-Blog.de: RSS Feed
Visit:  MSDN Online | Follow MSDN Online on Twitter | Follow Kay Giza on Twitter
Daily News on MSDN:  MSDN Aktuell
© Copyright 2006-2010 Kay Giza. All rights reserved. Legal
Subscribe

Refactoring to Patterns: Enum durch Strategy ersetzen mit verschiedenen Typen

04.11.2009 18:54:00 | Alexander Zeitler

Einer der Klassiker beim Refactoring ist das Ersetzen von Enums durch das Strategy-Pattern.

Wikipedia schreibt zum Enum:

Ein Aufzählungstyp (englisch enumerated type) ist ein Datentyp mit einem endlichen Wertebereich. Alle Werte des Aufzählungstyps werden bei der Deklaration des Typs mit Namen definiert. Dabei wird auch eine Reihenfolge festgelegt, die eine Ordnung der einzelnen Werte bestimmt, die Werte können also sortiert werden.

Die Wurzel des Übels

Und genau hier fängt auch das Problem an: Der Enum wird irgendwann eingeführt, um z.B. einen Status für eine Applikation abzubilden, als da wären AppState.Started, AppState.Stopped.

Irgendwann im Laufe des Lebenszyklus’ der Anwendung benötigen wir noch AppState.Paused und nochmal später AppState.Restarted.

Warum ist dies nun schlecht?

Der Grund ist, dass wir irgendwo (d.h. ziemlich sicher: an zig Stellen innerhalb unserer Applikation) AppState auch auswerten. Wenn wir nun neue AppStates einführen, müssen diese Stellen (Klassen) ebenfalls angepasst werden.

Dies ist ein Verstoß gegen das Open-Closed-Principle (OCP), das besagt, dass Software-Einheiten offen sein sollten für Erweiterungen, aber geschlossen für Modifikationen.

Besser ist es, deshalb, den Enum z.B. durch das Strategy-Pattern oder State-Pattern zu ersetzen.

Man sollte auch nochmal das Zitat oben beachten – der Enum hat einen endlichen Wertebereich, weshalb nicht alle Enums evil sind, z.B. hat ein Enum Wochentage sehr wohl seine Berechtigung.

Open. Closed. Principle

Bei den Arbeiten an einem Wrapper für ein internes Projekt ist mir folgendes Problem untergekommen:

Die Klasse CustomProperty besitzt eine Eigenschaft PropertyType, welche durch einen Enum abgebildet wird:

enum PropertyType { 
	CustomInfoUnknown, 
	CustomInfoText, 
	CustomInfoDate, 
	CustomInfoNumber, 
	CustomInfoDouble, 
	CustomInfoYesOrNo 
}

Abhängig von PropertyType soll die Ausgabe von CustomProperty anders formatiert werden – z.B. soll beim Double die Formatierung so aussehen:

string.Format(“Der Wert lautet {0}”, propertyValue");

Nun möchte ich natürlich nicht für jeden Datentyp eine eigene CustomProperty-Klasse entwickeln, weshalb sich hier Generics anbieten.

Außerdem ist die Formatierung eigentlich auch nicht Aufgabe der Property, denn ich möchte die Formatierung ja auch beliebig austauschen können.

Deshalb wird hierfür ein generischer CustomPropertyFormatter eingeführt, der an die CustomProperty bei der Instanzierung übergeben wird.

Somit werden wir auch noch einem weiteren SOLID-Principle gerecht: Single Responsibility Principle, kurz SRP.

Letztlich bin ich bei folgender Implementierung angekommen:

public class CustomProperty<T>
{
	private CustomPropertyFormatter<T> _formatter;
	private T _value;

	public CustomProperty(T propertyValue, CustomPropertyFormatter<T> formatter)
	{
		_formatter = formatter;
		_value = propertyValue;
	}

	T Value { get { return _value; } }

	public new string ToString()
	{
		return _formatter.ToString(_value);
	}
}

public interface ICustomPropertyFormatter<T>
{
	string ToString(T value);
}

public abstract class CustomPropertyFormatter<T> : ICustomPropertyFormatter<T> {
	public abstract string ToString(T value);

}

public class IntCustomPropertyFormatter : CustomPropertyFormatter<int> {
	public override string ToString(int value)
	{
		return string.Format("Die Zahl lautet {0}",value);
	}
}

Der Aufruf erfolgt über:

CustomProperty<int> property = 
	new CustomProperty<int>(5, new IntCustomPropertyFormatter());

Da ich mich selbst noch auf dem Weg zum CCD befinde, muss dieser Code nicht der Weisheit letzter Schluß sein – Anregungen und Kritik sind deshalb gerne willkommen ;-)

Danke an Chris und Peter fürs Zuhören / Diskutieren / Pair-Programming ;-)

MSDN Library: Neue Ansicht(en) in der kostenfrei zugaenglichen Online Bibliothek fuer Entwickler

04.11.2009 09:27:30 | Kay Giza

MSDN LibraryDie meisten von Ihnen werden unsere MSDN Library kennen, eine kostenfreie Online-Bibliothek mit tausenden Fachartikeln, SDKs und How-to-Anleitungen des M icrosoft Developer Network> (MSDN). Für mich und viele andere ist die MSDN Library ein unverzichtbares Nachschlagewerk geworden. Das zeigt auch das rege Feedback, das wir zu unserer Bibliothek bekommen und für das ich mich hiermit recht herzlich bedanken möchte. Wir versuchen, auf jede E-Mail sehr zeitnah einzugehen. Gute Nachricht habe ich daher für alle, die sich eine schnellere und einfacher zu navigierende MSDN Library gewünscht haben: Wir sind dabei, Ihren Wunsch Schritt für Schritt umzusetzen und unsere Online-Bibliothek immer weiter zu verbessern.

Ganz aktuell haben wir zwei neue Ansichten eingeführt, die ich Ihnen anhand des zufällig ausgewählten Artikels "Managed Extensibility Framework" von
Damir Dobric (MVP) vorstellen möchte:

Rechts unten auf jeder Seite können Sie zwischen den verschiedenen Ansichtsmöglichkeiten umschalten. Wir würden uns freuen, wenn Sie uns dort über die integrierte Feedback-Funktion (unten rechts auf der Seite) mitteilen, wie Ihnen die neuen Ansichten gefallen oder was wir noch besser machen könnten. Gerne können Sie zu dieser Thematik auch im MSDN Forum mit uns diskutieren.

Ich wünsche Ihnen ein angenehmeres und schnelleres Online-Erlebnis mit der MSDN Library!



This post is powered by www.Giza-Blog.de | Giza-Blog.de: RSS Feed
Visit:  MSDN Online | Follow MSDN Online on Twitter | Follow Kay Giza on Twitter
Daily News on MSDN:  MSDN Aktuell
© Copyright 2006-2010 Kay Giza. All rights reserved. Legal
Subscribe

www.asp-net-mvc.com

04.11.2009 00:33:02 | Jürgen Gutsch

Soeben bin ich auf Sean McAlinden's Blog gestoßen und zwar auf eine Beitrag, in dem Sean eine kleine Helferklasse beschreibt, mit der man relativ einfach an eingebettete Ressourcen kommen kann: ASP.Net MVC Embedded Resource Helper Class

Ganz unten unter Beitrag fand ich einen Link auf www.asp-net-mvc.com. Und da ich generell auf alles drauf klicke was irgendwie für ich interessant sein könnte. Fand ich eine Seite vor die sowohl von Sean McAlinden als auch von Paul Thorrington. Was zuerst aussieht wie eine kommerzielle Website entpuppte sich als Präsentation kleiner und feiner ASP.NET MVC Helfer. Insgesamt gibt es sieben kleine Helfer zum anschauen, herunterladen und nutzen.

http://www.asp-net-mvc.com/MvcHelpers

DotNetKicks-DE Image

Tools, Tools, Tools

04.11.2009 00:03:00 | Lars Schmitt

An dieser Stelle, möchte ich einmal kurz ein paar Programme Vorstellen, die mich bei meiner Arbeit unterstützen.
Möglicherweise ist auch für den ein oder anderen etwas nützliches dabei dabei.

Notpad ++
Ein sehr leistungsfähiger Open Source Editor, inklusive Syntax Highlighting, Suche mit Regulären Ausdrücken, Macros Funktionen.
 
Snoop
Bei der WPF Entwicklung, ist Snoop ein sehr Hilfreiches Tool bei der Untersuchung des Visual Trees, ein zusätzliches + wäre noch, dass man zur Laufzeit auch mal verschiedene Werte verändern kann.


Reflector
Vermutlich sollte jedem dieses kleine Tool ein Begriff sein, denn mit dieses Programm erlaubt ein Blick in die Sourcen Kompilierter Anwendungen.


Tortoise
Ein SVN/CVS-Client der sich in den Explorer einhängt und dem Entwickler somit das leben ein wenig erleichtert. 

Toad
Ein meiner Meinung nach ein sehr gutes Datenbank Frontend Tool
http://www.quest.com/toad-for-mysql/ (aber auch für andere DB verfügbar zb MS-SQL oder Oracle )

EQATEC-Profiler
Ein Profiler, zur Leistungsoptimierung damit auch die letzten Bremsen aus dem Programm verschwinden. 
Natürlich kann man auch verschiedene Programm Versionen miteinander Vergleichen.


Launchy (ich brauche es nur unter XP)
Da man sich durch Vista, oder Windows 7 an diese Schnellstartfunktion gewöhnt hat, hat der kleine Schnellstarter Launchy es auf meinen Firmen XP rechner geschaft. Einfach [Alt]+[Space] Programmname tippen [Enter] und schon startet das ganze.

WinMerge
Nicht nur in Verbindung mit Tortoise, ist dieses Tool sehr hilfreich beim Vergleichen von Text Dateien.


PowerCommands
DPack
Beide Plugins erweitern die IDE um ein paar sehr hilfreiche Features

Regionarate
Anordnen von QuellCode 

AnkhSvn
SVN Plugin für Visual Studio

PInvoke.Net (URL Tip: http://pinvoke.net/)
Sobald man Funktionen aus der Win32-Api benutzen möchte, wird an dieser Stelle die Aufrufe oder auch manchmal eine Beschreibung finden.

Das sind natürlich noch lange nicht alle Tools, die man den ganzen Tag so benutzt, aber es sind schon einmal die die einem auf Anhieb einfallen.

Thematik für das heutigen Kommentarfeld: Was für Tools helfen euch bei eurer Täglichen Arbeit?


Datenquelle in Registern Visualisieren (Korrektur)

03.11.2009 23:06:00 | Lars Schmitt

Die heutige Aufgabe:

Wie Visualisiere ich mehre Items einer Xml-Datenquelle, (kann natürlich auch für andere Datenquellen benutzt werden)  mittels WPF, in einer Register Darstellung.

Die Datenquelle besteht in diesem Beispiel, aus 100 zufällig ausgesuchten Datensätzen, der AdventureWorksCinema Sample DB.

an die Datenschützer unter euch, das sind Dummy Datensätze, Ähnlichkeiten mit der Realität wären reiner Zufall!

Nachdem man sich ein neues WPF Projekt erzeugt hat, fügt man als erstes die unten angehängt XML-Datenquellen, in das neue Projekt ein. (nicht vergessen in den Datei Eigenschaften ‘Copy To Output Directory’ auf zb ‘Copy if newer’ umzustellen)

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
  <Window.Resources>
    <XmlDataProvider x:Key="Contacts" Source="Contact.xml" XPath="contacts/ContactItem"/>
  </Window.Resources>
  <Grid>
    <ListView DataContext="{StaticResource Contacts}" ItemsSource="{Binding}">
      <ListView.View>
        <GridView>
          <GridViewColumn Header="Vorname" DisplayMemberBinding="{Binding XPath=FirstName}"/>
          <GridViewColumn Header="Nachname" DisplayMemberBinding="{Binding XPath=LastName}"/>
          <GridViewColumn Header="Telefon" DisplayMemberBinding="{Binding XPath=Phone}"/>
          <GridViewColumn Header="Email" DisplayMemberBinding="{Binding XPath=EmailAddress}"/>
        </GridView>
      </ListView.View>
    </ListView>
  </Grid>
</Window>

Der XmlDataProvider stellt die Daten, aus der XML-Datei, dem Window in seinen Resources zur Verfügung.Da es einfacher ist früh die Fehler zu erkennen, als später unter umständen, aufwendige Fehlersuchen bei den Grundlagen zu betreiben, habe ich an dieser Stelle schnell ein ListView mit Implementiert.

Soweit so gut, um die Datensätze zu Gruppieren nehme ich eine CollectionViewSource

  <Window.Resources>
    <XmlDataProvider x:Key="data" Source="Contact.xml" XPath="contacts/ContactItem"/>

    <CollectionViewSource x:Key="cvs" Source="{StaticResource data}">
      <CollectionViewSource.GroupDescriptions>
        <PropertyGroupDescription PropertyName="LastName" Converter="{StaticResource firstLetter}"/>
      </CollectionViewSource.GroupDescriptions>
    </CollectionViewSource>
  </Window.Resources>

Aktuell würden die Datenquellle anhand des Propperties Nachname Gruppiert werden, jedoch ist dies noch nicht ganz das was ich möchte. Ich könnte mir, eher eine Gruppierung, des ersten Buchstaben vom Nachnamens vorstellen. Zum Glück bietet die PropertyGroupDescription ein Property Namens Converter und der passende Converter ist schnell Implementiert.

using System;using System.Windows.Data;

namespace WpfApplication1
{
    public class FirstLetter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return value.ToString().Substring(0, 1);
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

Ich hätte zwar gerne einen SubStringConverter gehabt, jedoch suche ich noch ein Weg, dem Converter in dieser Konstellation ein Parameter mitzugeben. (Wer den Weg kennt, immer her damit, da unten sollte irgendwo ein Kommentarfeld sein, wer es findet darf etwas schreiben)

Die Datensätze werden nun nach dem ersten Buchstaben des Nachnamens gruppiert, jetzt brauche ich nur ein Steuerelement das mir das ganze anzeigt. Ich probiere es mal mit einem TabControl.

 





<TabControl DataContext="{StaticResource cvs}" ItemsSource="{Binding Path=Groups}">
  <TabControl.ItemTemplate>
    <DataTemplate>
      <StackPanel Orientation="Horizontal">
        <TextBlock Text="{Binding Path=Name}"/>
      </StackPanel>
    </DataTemplate>
  </TabControl.ItemTemplate>
</TabControl>

Die Items in jedem Tab, Visualisieren wir die einzelnen Daten im am ende in ein (nein, sagen ich mal besser in n) ListView’s.

 



<Grid>
  <TabControl DataContext="{StaticResource cvs}" ItemsSource="{Binding Path=Groups}">
    <TabControl.ItemTemplate>
      <DataTemplate>
        <StackPanel Orientation="Horizontal">
          <TextBlock Text="{Binding Path=Name}"/>
        </StackPanel>
      </DataTemplate>
    </TabControl.ItemTemplate>
    <TabControl.ContentTemplate>
      <DataTemplate>
        <ListView ItemsSource="{Binding Items}">
          <ListView.View>
            <GridView>
              <GridViewColumn Header="Vorname" DisplayMemberBinding="{Binding XPath=FirstName}"/>
              <GridViewColumn Header="Nachame" DisplayMemberBinding="{Binding XPath=LastName}"/>
              <GridViewColumn Header="Telefon" DisplayMemberBinding="{Binding XPath=Phone}"/>
              <GridViewColumn Header="Email" DisplayMemberBinding="{Binding XPath=EmailAddress}"/>
            </GridView>
          </ListView.View>
        </ListView>
      </DataTemplate>
    </TabControl.ContentTemplate>
  </TabControl>
</Grid>

nun haben wir nur noch ein kleinen Schönheitsfehler, unsere Register sind nicht Sortiert, aber auch an dieser Stelle kann die CollectionViewSource helfen.

 



<Window x:Class="WpfApplication1.Window1"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    xmlns:local="clr-namespace:WpfApplication1"    xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"    Title="Window1" Height="300" Width="300">
  <Window.Resources>
    <XmlDataProvider x:Key="data" Source="Contact.xml" XPath="contacts/ContactItem"/>
    <local:FirstLetter x:Key="firstLetter"/>
    <CollectionViewSource x:Key="cvs" Source="{StaticResource data}">
      <CollectionViewSource.GroupDescriptions>
        <PropertyGroupDescription PropertyName="LastName" Converter="{StaticResource firstLetter}"/>
      </CollectionViewSource.GroupDescriptions>
      <CollectionViewSource.SortDescriptions>
        <scm:SortDescription PropertyName="LastName"/>
      </CollectionViewSource.SortDescriptions>
    </CollectionViewSource>
  </Window.Resources>
  <Grid>
    <TabControl DataContext="{StaticResource cvs}" ItemsSource="{Binding Path=Groups}">
      <TabControl.ItemTemplate>
        <DataTemplate>
          <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding Path=Name}"/>
          </StackPanel>
        </DataTemplate>
      </TabControl.ItemTemplate>
      <TabControl.ContentTemplate>
        <DataTemplate>
          <ListView ItemsSource="{Binding Items}">
            <ListView.View>
              <GridView>
                <GridViewColumn Header="Vorname" DisplayMemberBinding="{Binding XPath=FirstName}"/>
                <GridViewColumn Header="Nachame" DisplayMemberBinding="{Binding XPath=LastName}"/>
                <GridViewColumn Header="Telefon" DisplayMemberBinding="{Binding XPath=Phone}"/>
                <GridViewColumn Header="Email" DisplayMemberBinding="{Binding XPath=EmailAddress}"/>
              </GridView>
            </ListView.View>
          </ListView>
        </DataTemplate>
      </TabControl.ContentTemplate>
    </TabControl>
  </Grid>
</Window>

und abschließen natürlich auch noch ein kleiner Screenshot, und ja es sind nur die Tabs vorhanden die auch Daten enthalten

Contact.xml

SharePoint 2010: Linq2SharePoint

03.11.2009 22:28:54 | Thorsten Hans

sp2010
Linq gehört mittlerweile zu den Basics in der .NET Welt, im SharePoint-Umfeld kann sich Linq erst mit erscheinen von SharePoint 2010 einen Namen machen. Es gab bereits für SharePoint 2007 einige Community Projekte die den MOSS Linq-Fähig gemacht haben, aber OOB wird Linq erst mit der neuen Version des SharePoint´s unterstützt.

 

Warum nun doch Linq?

Es gibt einige gute Gründe die für die Verwendung von Linq im SharePoint Umfeld sprechen:

  • CAML wird unnötig
  • Strengtypisierte Abfragen
  • Abfragesyntax wird zur Kompilierungszeit validiert
  • Unterstützung durch den intelligenten IntelliSense bei der Entwicklung von Abfragen
  • Listen werden als POCOS repräsentiert
  • Analoge Verwendung wie bei Linq2Entities oder Linq2Sql

Hallo SPMetal, einen Proxy bitte!

Wie ich bereits vor einigen Tagen in einem Post beschrieben habe, kann man durch SPMetal die für Linq2SharePoint benötigten Proxies automatisch generieren lassen.

Der Syntax ist wie ihr nachlesen könnt denkbar einfach.

   1:  SPMetal /web:http://mySP2010Server/DeveloperSite /code:DeveloperSite.cs 
 

Indem man den SPMetal aufruf als Pre-Build Ereignis einträgt, kann man sicherstellen dass die Proxies immer aktuell sind.

 

Das Herz von Linq2SharePoint der DataContext

Bei Linq2SharePoint ist der DataContext die Drehscheibe, jedes Query läuft (irgendwann) über den DataContext. Der DataContext für Linq2SharePoint ist an einer SPWeb Instanz.

Eine DataContext Instanz kann man einfach über den Konstruktor der Klasse definieren die wie bereits erwähnt als Parameter die SPWeb.URL erhält.

   1:  DataContext ctx = 
   2:      new DataContext(SPContext.Current.Web.Url);

 

Nachdem der entsprechende DataContext erstellt wurde muss man lediglich die Listen aus dem Context laden um Abfragen dagegen ausführen zu können.

   1:  List<HyperLink> links = ctx.GetList("Lists/Links");
 
Sowohl der DataContext als auch die eigentliche Liste aus dem SharePoint werden automatisch von dem durch SPMetal generierten Proxy verwaltet… Dennoch sollte man wissen was hinter den Kulissen geschieht!!

Ein komplettes Query mit Linq2SharePoint seht ihr hier

   1:  DataContext ctx = 
   2:     new DataContext(SPContext.Current.Web.Url);
   3:   
   4:  List<Task> tasks = ctx.GetList<Task>("Lists/DeveloperTasks");
   5:   
   6:  var importantTasks = 
   7:     from t in tasks
   8:     where t.Priority = 'High'
   9:     select t;
  10:   
  11:  foreach(var task in importantTasks)
  12:  {
  13:     Console.WriteLine(task.ToString());
  14:  }

 

Endlich Relational

Ebenfalls neu in SharePoint 2010 ist die Möglichkeit Daten relational abzubilden. Die wird in SharePoint 2010 über Lookup Fields erreicht. Natürlich sind die in SharePoint 2010 erstellten Relationen dann auch in Linq2SharePoint Queries voll unterstützt und die Abbildung von komplexen Geschäftsprozessen mit verknüpften Daten ist nun auch endlich in SharePoint möglich.

Zum Thema Relationale Daten in SharePoint 2010 werde ich demnächst noch etwas genauer schreiben. Hier ist aktuell nur interessant dass es funktioniert.

Ein dementsprechendes Linq2SharePoint Query unterscheidet sich nicht von anderen Linq Queries gegen eine relationale Datenquelle.

Hier ein kurzes Beispiel, welches alle Produkte eines Lieferanten aus SharePoint 2010 lädt

   1:  var products = 
   2:    from p in allProducts
   3:    where p.Supplier.ID ="4711"
   4:    select p;

 

Fazit

Dank Linq2SharePoint werden Abfragen gegen SharePoint nun endlich lesbarer und wartbarer als sie es noch in SharePoint 2007 dank CAML waren. Zwar gewöhnt man sich an alles aber es geht doch bedeutend einfacher! Oder?

 

DotNetKicks-DE Image

Datenquelle in Registern Visualisieren

03.11.2009 21:43:00 | Lars Schmitt

Die heutige Aufgabe:

Wie Visualisiere ich mehre Items einer Xml-Datenquelle, (kann natürlich auch für andere Datenquellen benutzt werden)  mittels WPF, in einer Register Darstellung.

Die Datenquelle besteht in diesem Beispiel, aus 100 zufällig ausgesuchten Datensätzen, der AdventureWorksCinema Sample DB.

an die Datenschützer unter euch, das sind Dummy Datensätze, Ähnlichkeiten mit der Realität wären reiner Zufall!

Nachdem man sich ein neues WPF erzeugt hat, fügt man als erstes die unten angehängt XML-Datenquellen, in das neue Projekt ein. (nicht vergessen in den Datei Eigenschaften ‘Copy To Output Directory’ auf zb ‘Copy if newer’ umzustellen)

 

Der XmlDataProvider stellt die Daten, aus der XML-Datei, dem Window in seinen Resources zur Verfügung.

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
 
    <Window.Resources>
        <XmlDataProvider x:Key="Contacts" Source="Contact.xml" XPath="contacts/ContactItem"/>
    </Window.Resources>
 
    <Grid>
        <ListView DataContext="{StaticResource Contacts}" ItemsSource="{Binding}">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Vorname" DisplayMemberBinding="{Binding XPath=FirstName}"/>
                    <GridViewColumn Header="Nachname" DisplayMemberBinding="{Binding XPath=LastName}"/>
                    <GridViewColumn Header="Telefon" DisplayMemberBinding="{Binding XPath=Phone}"/>
                    <GridViewColumn Header="Email" DisplayMemberBinding="{Binding XPath=EmailAddress}"/>
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
</Window>

Da es einfacher ist früh die Fehler zu erkennen, als später unter umständen, aufwendige Fehlersuchen bei den Grundlagen zu betreiben, habe ich an dieser Stelle schnell ein ListView mit Implementiert.

Soweit so gut, um die Datensätze zu Gruppieren nehme ich eine CollectionViewSource

<Window.Resources>
    <XmlDataProvider x:Key="data" Source="Contact.xml" XPath="contacts/ContactItem"/>
  
    <CollectionViewSource x:Key="cvs" Source="{StaticResource data}">
        <CollectionViewSource.GroupDescriptions>
            <PropertyGroupDescription PropertyName="LastName"/>
        </CollectionViewSource.GroupDescriptions>
    </CollectionViewSource>
</Window.Resources>

Aktuell würden die Datenquellle anhand des Propperties Nachname Gruppiert werden, jedoch ist dies noch nicht ganz das was ich möchte. Ich könnte mir, eher eine Gruppierung, des ersten Buchstaben vom Nachnamens vorstellen. Zum Glück bietet die PropertyGroupDescription ein Property Namens Converter und der passende Converter ist schnell Implementiert.

<Window.Resources>
    <XmlDataProvider x:Key="data" Source="Contact.xml" XPath="contacts/ContactItem"/>
 
    <local:FirstLetter x:Key="firstLetter"/>
  
    <CollectionViewSource x:Key="cvs" Source="{StaticResource data}">
        <CollectionViewSource.GroupDescriptions>
            <PropertyGroupDescription PropertyName="LastName" Converter="{StaticResource firstLetter}"/>
        </CollectionViewSource.GroupDescriptions>
    </CollectionViewSource>
</Window.Resources>

using System;
using System.Windows.Data;

namespace WpfApplication1
{
    public class FirstLetter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return value.ToString().Substring(0, 1);
        }
 
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}
 

Ich hätte zwar gerne einen SubStringConverter gehabt, jedoch suche ich noch ein Weg, dem Converter in dieser Konstellation ein Parameter mitzugeben. (Wer den Weg kennt, immer her damit, da unten sollte irgendwo ein Kommentarfeld sein, wer es findet darf etwas schreiben)

 

Die Datensätze werden nun nach dem ersten Buchstaben des Nachnamens gruppiert, jetzt brauche ich nur ein Steuerelement das mir das ganze anzeigt. Ich probiere es mal mit einem TabControl.

<TabControl DataContext="{StaticResource cvs}" ItemsSource="{Binding Path=Groups}">
    <TabControl.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Path=Name}"/>
            </StackPanel>
        </DataTemplate>
    </TabControl.ItemTemplate>
</TabControl>

Die Items in jedem Tab, Visualisieren wir die einzelnen Daten im am ende in ein (nein, sagen ich mal besser in n) ListView’s.

<Grid>
    <TabControl DataContext="{StaticResource cvs}" ItemsSource="{Binding Path=Groups}">
        <TabControl.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding Path=Name}"/>
                </StackPanel>
            </DataTemplate>
        </TabControl.ItemTemplate>
        <TabControl.ContentTemplate>
            <DataTemplate>
                <ListView ItemsSource="{Binding Items}">
                    <ListView.View>
                        <GridView>
                            <GridViewColumn Header="Vorname" DisplayMemberBinding="{Binding XPath=FirstName}"/>
                            <GridViewColumn Header="Nachame" DisplayMemberBinding="{Binding XPath=LastName}"/>
                            <GridViewColumn Header="Telefon" DisplayMemberBinding="{Binding XPath=Phone}"/>
                            <GridViewColumn Header="Email" DisplayMemberBinding="{Binding XPath=EmailAddress}"/>
                        </GridView>
                    </ListView.View>
                </ListView>
            </DataTemplate>
        </TabControl.ContentTemplate>
    </TabControl>
</Grid>

 

nun haben wir nur noch ein kleinen Schönheitsfehler, unsere Register sind nicht Sortiert, aber auch an dieser Stelle kann die CollectionViewSource helfen.

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1"
    xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
    Title="Window1" Height="300" Width="300">
 
    <Window.Resources>
        <XmlDataProvider x:Key="data" Source="Contact.xml" XPath="contacts/ContactItem"/>
 
        <local:FirstLetter x:Key="firstLetter"/>
 
 
        <CollectionViewSource x:Key="cvs" Source="{StaticResource data}">
            <CollectionViewSource.GroupDescriptions>
                <PropertyGroupDescription PropertyName="LastName" Converter="{StaticResource firstLetter}"/>
            </CollectionViewSource.GroupDescriptions>
            <CollectionViewSource.SortDescriptions>
                <scm:SortDescription PropertyName="LastName"/>
            </CollectionViewSource.SortDescriptions>
        </CollectionViewSource>
    </Window.Resources>
 
    <Grid>
        <TabControl DataContext="{StaticResource cvs}" ItemsSource="{Binding Path=Groups}">
            <TabControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Path=Name}"/>
                    </StackPanel>
                </DataTemplate>
            </TabControl.ItemTemplate>
            <TabControl.ContentTemplate>
                <DataTemplate>
                    <ListView ItemsSource="{Binding Items}">
                        <ListView.View>
                            <GridView>
                                <GridViewColumn Header="Vorname" DisplayMemberBinding="{Binding XPath=FirstName}"/>
                                <GridViewColumn Header="Nachame" DisplayMemberBinding="{Binding XPath=LastName}"/>
                                <GridViewColumn Header="Telefon" DisplayMemberBinding="{Binding XPath=Phone}"/>
                                <GridViewColumn Header="Email" DisplayMemberBinding="{Binding XPath=EmailAddress}"/>
                            </GridView>
                        </ListView.View>
                    </ListView>
                </DataTemplate>
            </TabControl.ContentTemplate>
        </TabControl>
    </Grid>
</Window>

und abschließen natürlich auch noch ein kleiner Screenshot, und ja es sind nur die Tabs vorhanden die auch Daten enthalten
 



Visual Studio 2010 Beta 2 Startup beschleunigen

03.11.2009 18:02:00 | Thorsten Hans

Niall Merrigan zeigt in einem Blogpost wie man den Start der neuen Visual Studio 2010 Beta um einiges :D beschleunigen kann. Laut seiner Analyse startet VS2010 bei ihm nun in 2 anstatt 25 Sekunden. In meienm VirtualPC startet VS2010 nach dem Patch in 5 Sekunden anstatt in 32 Sekunden.

Hier kurz die Zusammenfassung der auszuführenden Schritte:

 

  1. Alle Visual Studio Instanzen schließen
  2. Registrierungseditor (regedit) öffnen
  3. Den Schlüssel HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\10.0 selektieren
  4. Hier einen neuen Schlüssel mit dem Namen “ClrHost” (ohne Anführungszeichen) anlegen
  5. Den neuen Schlüssel öffnen und einen DWORD32 mit dem Namen “StartupFlags” (ebenfalls ohne Anführungszeichen) anlegen und den Wert auf 5 setzen
  6. Registrierungseditor schließen und Visual Studio 2010 Beta 2 erneut starten.
DotNetKicks-DE Image

.NET Usergroup Saar

03.11.2009 16:55:27 | Thorsten Hans

 

Da bis Dato im Saarland noch keine UserGroup für .Net Entwickler und .Net Interessierte bestanden hat, haben Christian Glessner und ich uns entschlossen nun endlich eine eigene UserGroupdnugsaar_logo zu gründen.

Wie unschwer zu erraten ist, wird sich bei den regelmäßigen Treffen alles rund ums Thema .NET Entwicklung drehen. Wir beabsichtigen die Treffen je nach Resonanz im Monats beziehungsweise Zwei-Monats Rhythmus zu veranstalten.

Ein Dankeschön gilt auch unserem Arbeitgeber der Data One GmbH die für die Usergroup Treffen die entsprechende Location zur Verfügung stellt.

Zunächst werden alle Informationen rund um die UserGroup in der entsprechenden Xing-Gruppe veröffentlicht, jedoch wird auch eine öffentliche Website sowie die Angliederung an die INETA noch folgen.

 

Technorati-Tags: ,
DotNetKicks-DE Image

Lokalisierung von WPF Anwendungen: Einführung

03.11.2009 15:31:03 | Mathias Raacke

Anwendungen sollen oft in verschiedenen Märkten angeboten werden. Dazu müssen sie verschiedene Sprachen unterstützen, d.h. sie müssen lokalisierbar sein. Resourcen wie Texte usw. müssen also sprachabhängig austauschbar sein.

Rückblick: Lokalisierung in Windows Forms

Betrachten wir zunächst die Lokalisierung von Windows Forms Anwendungen: Windows Forms Formulare sind direkt über den Designer lokalisierbar. Dafür gibt es die Eigenschaften Localizable und Language.

image

Stellt man Localizable auf true, kann man über Language die Sprache des Formulars wechseln und das Formular direkt im Designer in der gewählten Sprache bearbeiten.

Zu jeder Sprache, die man auf diese Weise erstellt, erzeugt Visual Studio eine Ressourcendatei, in der die Texte und sonstige Formular-Eigenschaften der Sprache gespeichert werden.

image

Ressourcendateien sind außerdem direkt in Visual Studio bearbeitbar.

image

Für jede Sprache erzeugt Visual Studio eine sogenannte Satellitenassembly mit den Ressourcen der jeweiligen Sprache. Zur Anwendung Beispiel.exe gibt es also dann z.B. Unterordner de-DE\Beispiel.resources.dll und en-US\Beispiel.resources.dll. Abhängig von der aktuell im Thread eingestellten Sprache lädt die Anwendung automatisch die Ressourcen aus der passenden Satellitenassembly.

Lokalisierung in WPF

Man sollte meinen, in WPF als Nachfolgetechnologie zu Windows Forms müsste die Lokalisierung mindestens genauso gut funktionieren, idealerweise sollte alles noch einfacher gehen.

Das ist jedoch nicht so. Eigenschaften wie Localizable und Language fehlen im Designer.

image

Tatsächlich gibt es überhaupt keine eingebauten Lokalisierungswerkzeuge in Visual Studio oder Blend. Stattdessen gibt es eine API, mit der man solche Tools zunächst selbst schreiben soll. Zu dieser API gibt es außerdem ein Beispiel-Tool, locbaml, das aber wirklich nur ein Beispiel ist und deshalb in der Praxis nicht brauchbar ist.

In den nächsten Wochen werde ich über einige Ansätze zur WPF Lokalisierung schreiben.

Technorati Tags: ,

Blogsprache

03.11.2009 13:19:00 | Thorsten Hans

Auf Anraten von Christian Glessner stelle ich hier einfach mal die Frage ob ich meinen Blog auf deutsch oder auf englisch führen soll? Bitte gebt eure Meinung via Kommentar ab.

 

Danke

DotNetKicks-DE Image

SharePoint 2010 Certifications

03.11.2009 12:35:00 | Thorsten Hans

Die offizielle Beta von SharePoint 2010 ist noch nicht released und bereits jetzt gibt es schon Informationen über die neuen Zertifizierungen für den SharePoint.

Analog zu allen anderen Zertifizierungen wird es nun auch im SharePoint Metier den MCTIP und den MCPD Pfad geben die beide benötigt werden um sich als Microsoft Certified Master (MCM) for SharePoint 2010 zertifizieren zu lassen.

SharePoint 2010 Zertifizierungen für Entwickler

70-573: Microsoft SharePoint 2010 Application Development (MCTS)

70-576: Designing and Developing Microsoft SharePoint 2010 Applications (MCPD)

SharePoint 2010 Zertifizierungen für IT Pros

70-667: Microsoft SharePoint 2010 Configuration (MCTS)

70-668: SharePoint 2010 Administrator (MCITP)

 

Die Zertifizierungen werden ab Juni 2010 verfügbar sein, wann diese eventuell im Beta Programm erscheinen ist noch nicht bekannt. Weitere Informationen zu diesen Zertifizierungen findet Ihr auf dieser Microsoft Partner Seite.

 

DotNetKicks-DE Image

MSBuild: Wildcards im Copy-Task

03.11.2009 09:29:00 | Martin Hey

Mit dem Copy-Task in MSBuild-Skripten kann man - wie der Name nicht anders vermuten ließ - Dateien von einem Ort zu einem anderen kopieren. Dabei gibt man im Attribut SourceFiles die zu kopierende(n) Datei(en) an und den Zielordner im Attribut DestinationFolder. Alternativ kann man auch das Attribut DestinationFiles verwenden und damit gleich eine Umbenennung der Datei(en) vornehmen.
<Copy SourceFiles="$(ProjectDir)\Resources\LanguageResourceCZ.xml;$(ProjectDir)\Resources\LanguageResourceDE.xml" DestinationFiles="$(LanguageResourcesPath)\CZ\LanguageResource.xml;$(LanguageResourcesPath)\DE\LanguageResource.xml" />
<Copy SourceFiles="$(ProjectDir)\Resources\LanguageResourceCZ.xml;$(ProjectDir)\Resources\LanguageResourceDE.xml" DestinationFolder="$(LanguageResourcesPath)" />

Interessant wird es dann, wenn man versucht, die Quelldateien per Wildcard auszuwählen. Der Versuch wird mit einer Fehlermeldung quittiert:
Error MSB3021: Unable to copy file "C:\Entwicklung\Resources\*.*" to "C:\Deploy\Resources". Illegal characters in path.

Wie für alles gibt es auch hierfür eine Lösung. Man erzeugt zunächst ein Item - denn hier kann man Wildcards verwenden - und übergibt dieses dann dem Copy-Task.
<CreateItem Include="$(ProjectDir)\Resources\*.*">
<Output TaskParameter="Include" ItemName="ResFiles" />
</CreateItem>
<Copy SourceFiles="@(ResFiles)" DestinationFolder="$(LanguageResourcesPath)" />

Damit sind Wildcards auf einer Ebene möglich. Manchmal möchte man auch rekursiv kopieren. Dazu gibt es einen guten Eintrag im MSBuild Team Blog. Zunächst werden die Dateien in einer ItemGroup zusammengefasst und dann dem Copy-Task übergeben. Dabei bestimmt der Wildcard **, dass eine rekursive Auswahl erfolgen soll. Das Metadatum %(RecursiveDir) wird dann verwendet, um die Daten auch wieder rekursiv in der korrekten Ordnerstruktur ablegen zu können.

<ItemGroup>
<Compile Include="$(ProjectDir)\Resources\**\*.*" />
</ItemGroup>
<Copy SourceFiles="@(Compile)" DestinationFolder="$(LanguageResourcesPath)\%(RecursiveDir)" />

Wenns schneller gehen muss: Precompiled Linq Queries

03.11.2009 08:01:00 | Thorsten Hans

Performance, Performance, Performance! Wenn es auch bei euch darum geht die Geschwindigkeit einer Code-Pasage zu verbessern und ihr der Meinung seit, dass es eigentlich nicht mehr schneller geht, solltet ihr nicht vergessen eure Linq-Queries vorzukompilieren. Die Klasse CompiledQuery aus dem Namespace System.Data.Objects ist hierzu das nötige Helferlein.

 

Die generische Methode Compile der Klasse kann dazu verwendet werden um ein einfaches Linq-Query vorzukompilieren damit es zur Laufzeit performanter ausgeführt werden kann. Die Methode stellt genügend Überladungen bereit um die meisten Bedürfnisse abzudecken.

Eine Übersicht aller Überladungen der Methode findet Ihr hier.

Die Verwendung der Methode ist denkbar einfach, wie das nachfolgende Beispiel zeigt

 

   1:  // Ausgangscode
   2:  var products = from p in myContext.Products 
   3:                           where p.CategoryId = '1'
   4:                           select p

 

Zunächst definiert man eine Variable die das vorkompilierte Query speichern soll

   1:  Func<MyObjectContext, String, IQueryable<Product>> getProductsById;

 

Nun kommt die Zuweisung und die eigentliche Vorkompilierungsanweisung

   1:  getProductsById = 
   2:   CompiledQuery.Compile<MyObjectContext, String, IQueryable<Products>>
   3:   ((MyObjectContext context, String filterCondition) 
   4:     => from p in context.Products
   5:        where p.CategoryId = filterCondition
   6:        select p);

 

Zum Schluss noch ein Beispiel für die spätere Verwendung des vorkompilierten Queries

   1:  // alle Produkte der Kategorie 4 abrufen
   2:  var products = 
   3:      getProductsById.Invoke(MyRepository.Context, "4");

 

Mit diesen einfachen Schritten kann man die Ausführung von Linq Queries beschleunigen und somit nochmals an der Code-Performance bzw. Anwendungsperformance schrauben.

 

DotNetKicks-DE Image

HowTo: Eine eigene ConfigSection schreiben / Custom ConfigSections

03.11.2009 00:11:07 | Robert Mühsig

.NET bietet eine recht einfache Möglichkeit Applikations Einstellungen in eine .config zu speichern. Wenn allerdings die Anwendung und damit das “einstellbare” komplexer wird, reicht vielleicht die einfachen AppSettings nicht aus. In diesem HowTo geht es darum, wie man seine komplett eigenen Custom ConfigSections bauen kann.   Wie soll unsere Konfiguration am Ende aussehen? Im meinem Beispiel stellen [...]SHARETHIS.addEntry({ title: "HowTo: Eine eigene ConfigSection schreiben / Custom ConfigSections", url: "http://code-inside.de/blog/2009/11/03/howto-eine-eigene-configsection-schreiben-custom-configsections/" });

Hyper-V Snapshots

02.11.2009 21:12:19 | Thomas Schissler

Hype-V ist ein klasse Virtualisierungssystem das vor allem in der neuesten Version eine Reihe nützlicher Funktionen mitbringt. Besonders hilfreich sind Snapshots mit denen es gefahrlos möglich ist, auch auf dem Server mal was zu testen. Man kann sich aber mit Shanpshots leicht selber überlicsten oder gar in’s Knie schießen. Deshalb möchte ich hier ein paar Erfahrungen zum Besten geben:

Funktionsweise von Snapshots

Die Virtuellen Maschinen von Hyper-V schreiben ihre Daten in virtuelle Harddisks (VHD), also eine Datei auf der Platte des Hosts. Wird nun ein Snapshot gemacht, passiert vereinfach gesagt, Folgendes. Die VHD-Datei wird schreibgeschützt, so dass daran keine Änderungen mehr vorgenommen werden können. Statt dessen wird nun eine AVHD-Datei angelegt und alle Änderungen auf der Platte der VM werden nun dort hineingeschrieben. Wird erneut ein Snapshot erstellt, wird die AVHD gesperrt und eine weitere angelegt.

image

Dies hat nun zweierlei Folgen:

  1. Je mehr Snapshots erstellt werden, desto langsamer wird der Zugriff auf die virtuelle Disk, da Hyper-V ja aus der VHD und den verschiedenen AVHDs nun die Daten zusammensammeln muss.
  2. Nur die VHD und alle AVHDs zusammen ergeben den aktuellen Stand der virtuellen Disk, mit der VHD alleine hat man nur den Stand vom ersten Snapshot.

Gerade der letzte Punkt ist beim Verschienen der VM oder beim Backup zu berücksichtigen, da man hier schnell Daten verlieren kann, wenn man vergisst die AVHDs zu berücksichtigen.

Aus beiden oben genannten Gründen macht es Sinn, Snapshots zu löschen, sobald diese nicht mehr gebraucht werden. Snapshots sind keine Technik zur Erstellung von Backups! Zum löschen eines Snapshots wird dieser einfach selektiert und dann mit “Delete” gelöscht. Aber ACHTUNG! Die Daten liegen nun immer noch in der AVHD. Erst wenn man die VM in den Save-State fährt, beginnt Hyper-V mit einem Merge, d.h. die Änderungen der AVHDs werden jetzt in die jeweils vorausgegangene AVHD bzw. VHD gemerged, sind alle Snapshots gelöscht, bleibt nur noch die VHD übrig.

image

Erst nach Abschluss des Merge-Vorgangs erhält man durch eine Kopie der VHD eine komplette Sicherung der virtuellen Disk der VM.

Visual Studio 2010 Editionen im Vergleich

02.11.2009 18:52:00 | Thorsten Hans

Auf der Produktseite von Visual Studio 2010 kann man nun auch die einzelnen Editionen miteinander vergleichen und sich somit schon jetzt Gründe aussuchen wie man seinem Chef nahelegt die Ultimate Edition von Visual Studio 2010 zu kaufen… :D

DotNetKicks-DE Image

Stirnrunzeln über “Wie viel Sinn machen Unittests?”

02.11.2009 01:44:01 | Jürgen Gutsch

Seit Oktober 2009 verfolge ich mit Begeisterung das Streitgespräch zwischen Golo Roden und Peter Bucher. Beide Autoren stellen sich jeden Monat von neuem diversen Fragen und Problemen aus dem Bereich der Softwareentwicklung.

Auch dieses mal kann man wieder über ein Spannendes Thema lesen: Wie viel Sinn machen Unittests?

Diesmal allerdings fühle ich mich gezwungen selber ein Kommentar über den neuesten Beitrag zu schreiben. Denn das erste mal seit dieser Serie bin ich sehr erstaunt, bzw. sogar leicht erschreckt, über Golos Beitrag.

So schreibt Golo, dass Unit Tests zwar wünschenswert sind und und durchaus Sinn machen, allerdings nur an explizit ausgewällten Stellen:

Golo schrieb:
Wie viel Sinn machen Unittests also nun? Zusammengefasst kann man sagen, dass Unittests – an der richtigen Stelle eingesetzt – durchaus Sinn ergeben, dass diese Stellen aber explizit ausgewählt werden sollten.

Des weiteren schreibt er, dass eine 100%ige Testabdeckung zwar wünschenswert ist, aber in der Praxis kaum möglich ist und sogar auf kosten der OOP geht.

Als Begründung nennt er drei Aspekte, auf die ich hier etwas eingehen möchte:

Golo schrieb:
Der bestehende objektorientierte Aufbau ist unter OOP- und stilistischen Aspekten sauber umgesetzt, läuft einer guten Testbarkeit allerdings zuwider.

Diesen ersten Aspekt kann ich leider nicht nachvollziehen, bzw. halte ihn aus meiner Erfahrung heraus sogar für paradox. Im Gegenteil bin ich der Meinung, dass eine saubere, allen Regeln des OOP entsprechende Architektur testbarer ist. Ich gehe sogar noch weiter und behaupte, dass eine mir TDD umgesetzte Anwendung OOP besser umsetzen kann als eine, nicht mit Unit Tests abgedeckte Anwendung.

Denkt man darüber nach was Unit Tests eigentlich sind, nämlich Tests der kleinsten vorhandenen Units, beeinträchtig das keineswegs negativ den aufbau der Anwendung nach allen regeln der OOP. Ein Unit Test testet die kleineste ansprechbare Einheit einer Klasse, das ist eine Methode oder eine Eigenschaft, aber weder deren Abhängigkeiten, noch komplexe Routinen und Szenarien.

Unit Tests unterbinden Abhängigkeiten:

Golo schrieb:
Es bestehen zahlreiche Abhängigkeiten zu externen Komponenten, die sich nicht oder nur mit sehr viel Aufwand simulieren lassen.

Eine saubere Architektur besteht ohne Abhängigkeiten. Mit Hilfe von IoC Containern und Dependency Injection werden Abhängigkeiten gelöst. Dadurch lassen sich die einzelnen Units noch einfacher Testen. Dadurch lassen sich z. B. ohne Aufwand andere spezielle für diese Tests benötigte Bibliotheken laden. Das wiederspricht also schon dem zweiten Aspekt. Beispielswiese lässt sich für den Unit Test eine Library laden, die den Zugriff auf eine Im-Memory-Datenbank ermöglicht, statt auf einen SQL Server Datenbank.

Eine weitere Möglichkeit sich in in Unit Tests von Abhängigkeiten zu lösen sind Mocking Frameworks wie z. B: RhinoMocks:

Golo schrieb:
Es bestehen Abhängigkeiten zur konkreten Laufzeitumgebung, die sich nicht oder nur mit sehr viel Aufwand nachbilden lassen.

Mocking Frameworks werden genutzt um z. B. abhängige Klassen zu simulieren. Anhand eines Interfaces werden “gefälschte” Objekte erzeigt, die lediglich die benötigten Funktionen bereitstellen und die gewünschten werte liefern.

Datenzugriffsklassen, Dateienzugriffsklassen, eigentlich alle Abhängigkeiten lassen sich in einer sauberen Umgebung simulieren und der Unit Test konzentriert sich einzig und allein auf das Unit, statt Abhängigkeiten berücksichtigen zu müssen.

Golo schrieb:
Um Webbrowser-spezifisches Verhalten zu simulieren, müssten die Eigenheiten des jeweiligen Webbrowsers im Unittest nachgebildet werden. Alternativ könnten der entsprechenden gewünschte Webbrowser automatisiert werden – was seinerseits allerdings einen ziemlichen Aufwand nach sich zieht.

Das ist meiner Meinung nach die Aufgabe eines integrationstests, nicht die eines Unit Tests. Da hier ein komplettverhalten getestet wird und nicht das Verhalten einer einzelnen Unit. Um diese Unit zu testen muss der HttpRequest der von der Unit benötigt wird, simuliert werden.

Golo schrieb:
Ebenfalls problematisch ist multithreaded Code, sofern bestimmte Konstellationen in den einzelnen Threads getestet werden sollen – da das Umschalten zwischen den Threads vom aktuellen Kontext des Prozessors beziehungsweise des Betriebssystems abhängt, kann sich das Verhalten von Ausführung zu Ausführung unterscheiden.

Auch hier sollte der Unit Test nicht den Thread testen , sondern die Units die innerhalb der Threads arbeiten, alles andere wäre kein Unit Test.

Mein Fazit:

Die Benutzung von Unit Tests von möglichen Abhängigkeiten “abhängig zu machen” ist in Zeiten mit IOC Containern und Mocking Frameworks nicht mehr haltbar. Mit Hilfe von diesen Hilfsmitteln ist garantiert eine Testabdeckung von annähernd 100% machbar.

Update:

Hier noch ein Statement zum Thema von Thomas Bandt.

Lesenswert sind auch die Kommentare zu Golos Beitrag unter anderem auch von Ralf Westphal.

Mein Fazit (das zweite):

Wie Thomas kann ich bestätigen dass TDD am Anfang sehr, sehr schwierig ist. Wenn man Jahrelang einfach drauf los entwickelt hat, ist es ein wahrer Kraftakt und es erfordert eine menge Konzentration uns Selbstdisziplin Testgetrieben zu entwickeln.

DotNetKicks-DE Image

Git in Visual Studio 2010 und 2008/05 ohne AddIn verwenden

01.11.2009 12:44:45 | Albert Weinert

Verteilte Versionskontrolle ist der “neueste” Schrei, am lautesten wird derzeit wohl bei Git geschrieben.

Ein Problem was wohl viele davon abhält Git zu verwenden ist die fehlende Integration in Visual Studio. Mich am Anfang auch, ich konnte es mir halt nicht vorstellen das sowas wie das umbennen von Datein oder das hinzufügen von neuen Dateien einfach so funktioniert ohne dass man ständig drüber nachdenken muss.

Bei Subversion z.B. muss man alle Änderungen an Dateinamen oder neue Dateien mit Subversion selbst machen. Macht man dies nicht kommt man in Teufels Küche. Damit man auch da nicht immer drüber nachdenken gibt es für Subversion AddIns für Visual Studio die einem die Arbeit im Hintergrund einfach abnehmen so dass man unbeschwert damit arbeiten kann.

Bei Git ist dies nicht so nötig. Mit einer ordentlichen .gitignore Datei findet Git zuverlässig hinzugefügten und gelöschten Dateien, und schafft es auch Unbenennungen selbständig aufzulösen. Warum nicht gleich so. Deshalb lieben es die Git Puristen auf der Shell zu arbeiten und alles über die Kommandozeile zu machen. Dazu gehöre ich nicht und wollte auch lange eine Visual Studio integration.

Seit ein paar Tagen beschäftige ich mich intensiver mit Git und stelle fest; man braucht keine Integration wie man sie von VisualSVN oder AnkhSVN gewohnt ist. Aber Kommandozeile war mir doch zu nervig auf dauer.

Jedoch kann man Visual Studio mit ein paar Handgriffen so anpassen dass man Git mit ein paar Mausklicks und Tastatur bedienen kann sowie auf die Git GUI zugreifen kann.

image Die Magie liegt in der Verwendung von Git als External Tool in Visual Studio. Darin kann man sich die gewünschten Git Kommandos eintragen und in Toolbars sowie mit Tastatur verwenden.

Die Ausgaben der einzelnen Befehle können dann im Output-Window angezeigt werden.

image

Exemplarisch zeige ich die Schritte mit Visual Studio 2010, dies funktioniert jedoch auch mit Visual Studio 2008 und den Vorversionen.

Über das Menü Tools->External Tools gelangt man in die Konfiguration der External Tools.

image

Dies sind die aktuell bei mir eingestellten Befehle, keine Ahnung ob die representativ sind. Sie spiegeln dass wieder was ich gerade brauche und werden sich wohl in Zukunft ändern. Screenshots von den Parametern der einzelnen Befehle folgen weiter unten.

Wenn man sich die externen Tools so eingestellt hat wie man sie braucht muss man sich nur noch eine neue Toolbar erstellen und die Tools einbinden. Dazu einfach über das Menü Tools->Customize in die Toolbar-Anpassung wechseln.

image

Einfach eine neue Toolbar erstellen und benennt sie nach Wahl, Git bietet sich an.

image Danach findet sich in Visual Studio eine leere Toolbar. Nun muss man diese nur noch mit Leben füllen, dazu wechselt man auf den Commands-Tab auf dem Customize-Dialog und wählt die erstellte Toolbar aus. Der kurze Wege dahin ist über den kleine Menü-Dropdown am Ende der Toolbar. Dort einfach Customize auswählen und schon ist man an der richtigen Stelle im Dialog.

image

Über Add Command… wählt man nun ein Kommando nach dem anderen aus und fügt es der Toolbar hinzu.

image

Leider wird nicht der eingetragene Befehle angezeigt, sondern nur External Command 1-24. Wobei bei mir Visual Studio 2010 Beta 2 die Kommandos 4 und 5 in der Liste unterschlägt, Visual Studio 2008 macht dies nicht.

image

Das Git am Anfang fügte ich über Add New Menü hinzu, diese ist als Toolbar Git | Git auch verfügbar und könnte mit den selten genutzteren Befehlen bestückt werden.

Bei den einzelnen Einträgen wird als Vorsteinstellung der eingetragene Titel des Kommandos verwendet, diesen kann man über Modify Selection anpassen.

Über die Git Gui kann auf einfache Weise die funktionalitäten wie Branchen, Mergen oder Commits mit ausführlichen Kommentar ausführen. Geht natürlich auch alles über die Kommandozeile, aber nett ist es schon.

image

Das war es auch schon was man zum arbeiten mit Git in Visual Studio braucht, der Vorteil ist das man nicht auf irgendwelche AddIns für neuen Visual Studio Versionen warten muss.

Hier nun die Einstellungen für die Externals Tools für Git bei mir.

Alle neuen Dateien zum Git Repository hinzufügen

image

Vorschau der Dateien die zum Git Repository hinzugefügt werden

image

Status über die anstehenden Änderungen

image

Zum lokalen Git Repository hinzufügen und alle neuen Dateien hinzufügen

image

Die Git Gui

image

Update der Änderungen aus dem zentralem Subversion Repository

Wenn man Git als lokales Repository verwendet besteht die Möglichkeit gegen ein zentrales Subversion Repository zu arbeiten. So ist ein Umstieg sehr einfach und man lokal die Vorteile von Git nutzen.

image

Commit ins zentrale Subversion Repository

Macht für alle Änderungen die zwischenzeitlich ins lokale Git Repository committed worden sind entsprechende Commits nach Subversion ins Zentrale Repository.

image

Für Verbesserungsvorschläge und Hinweise schreibt einfach was in die Kommentare, ich stehe ja noch am Anfang meiner Erfahrungen mit Git.

Wieviel Sinn machen Unittests?

01.11.2009 09:37:00 | Peter Bucher

Am 13. Oktober 2008 haben Golo Roden und ich unter dem Titel Noch Fragen, Roden? Ja, Bucher! angekündigt, jeweils zum ersten eines jeden Monats einen Kommentar zu einem vorab gemeinsam gewählten Thema verfassen zu wollen.
Außerdem nimmt diesen Monat auch Christian Wenz wieder an unserem Streitgespräch teil.

Bisher sind in dieser Reihe folgende Kommentare erschienen:

Heute, am 1. November 2009, ist es nun wieder so weit, und unser Thema für diesen Monat lautet:

Wieviel Sinn machen Unittests?

So wohl Golo wie auch ich haben uns unabhängig voneinander im Vorfeld unsere Gedanken gemacht, wie wir diesem Thema gegenüberstehen. Golos Kommentar findet sich zeitgleich in seinem Blog, folgend nun mein Kommentar zu diesem Thema:

Schon in einem früheren Streitgespräch “Die Forderung nach Softwarequalität” habe ich Unittests erwähnt.

Ich würde als direkte Antwort natürlich gleich sagen: Sehr viel Sinn!
Jedoch muss die Frage irgendwie auseinandergenommen werden, denn generell lässt sie sich nicht beantworten.

Wo macht Unittesting Sinn?

Grundsätzlich macht es überall Sinn, wo das Verfahren leicht anzuwenden ist, ohne irgendwelche Handstände zu machen.

Schwierige Testumgebungen

Gerade in der Webentwicklung bzw. überall wo eine Oberfläche vorhanden ist, wird es schwieriger Abläufe zu testen.

Handelsübliche ASP.NET (WebForms) Anwendungen die schon entwickelt sind, jedoch nachträglich getestet werden müssen, eigenen sich überhaupt nicht dazu, nachträglich mit Unittesting zu versorgt zu werden.
Das liegt daran dass die Zuständigkeiten (Concerns) physikalisch und auch logisch nicht strikt getrennt sind, sondern schlussendlich bei den meisten Anwendungen irgendwo in den Page-Eventhandlern liegt.

Zum “nachträglich” kommen wir dann später noch mal zurück.

Wenn eine ASP.NET Anwendung von Grund auf neu entwickelt wird, kann das MVP (Model View Presenter)-Pattern eingesetzt werden, damit Unittests überhaupt eingesetzt werden können.
Wiederum gibt es ASP.NET MVC, das – wie der Name schon sagt – auf das MVC (Model View Controller)-Pattern setzt, was die Testbarkeit um einiges vereinfacht.
Natürlich gibt es auch dort noch Hürden und auch eine ASP.NET MVC Anwendung kann so geschrieben werden, das sie kaum noch testbar ist.

Für solche schwer testbare Anwendungen sind Oberflächentests der bessere bzw. möglichere Weg und stellen auch einen zusätzlichen Weg dar, für Anwendungen die schon mit Unittests abgedeckt sind.

Optimale Testumgebungen

Am besten eigenen sich kleine Greenfield (Start von der grünen Wiese aus)-Projekte, die – wenn möglich – Bibliotheken sind, die dann später in die Oberfläche integriert werden, bzw. ihre Aufgabe aufgrund einer Aktion der Oberfläche erfüllen.

Ein super Beispiel dafür ist die Entwicklung eines Dependency Injection Containers. Da kann man sogar hergehen und komplett testgetrieben arbeiten, also zuerst den Test und dann der Produktivcode, weil keine äusseren Abhängigkeit oder Oberflächen mit von der Partie sind.
Schlussendlich kann dann so sichergestellt werden, dass der Code das tut, was er sollte, zumindest in den getesteten Szenarien.

Lizenznummern generieren, parsen, zählen, prüfen, auch das ist ein super Beispiel wo Unittesting sehr gut angewendet werden kann, wenn es richtig aufgezogen wird.
Ich würde sogar behaupten es wäre fast unmöglich ohne irgendwelche Tests (Und hier eigenen sich Unittests am besten), so eine Bibliothek aufzubauen und sicherzustellen, damit sie korrekt funktioniert.

Denn erstens kann so sichergestellt werden, dass sich das implementierte Verhalten auch so verhält, wie es der Test vorschreibt und zweitens können Seiteneffekte entdeckt, behoben und schlussendlich ausgeschlossen werden. Denn nach jedem zusätzlich geschriebenen Test, sollten alle Tests noch einmal durchlaufen, so können dann Seiteneffekte erkannt und behoben werden.

Wieviel Testabdeckung ist sinnvoll?

Vielerorts wird geschrieben und gesagt das 100% Testabdeckung das Ziel sein sollte. Ich sage, das es gut ist, seine Ziele hochzustecken. Jedoch sind eben die letzten paar Prozent fast nicht testbar, oder es macht keinen Sinn sie zu testen, entweder weil es viel zu aufwändig ist, oder der Code schon durch Integrationstests abgedeckt ist.

Nachträgliches Unittesting?

Eine Anwendung nachträglich mit Unittests abzudecken macht m.E. nicht sehr viel Sinn.
Es gibt zuviel Aufwand und die Anwendung bzw. dessen Abläufe und verstrickter Code soll bestimmen, wie / wo und was getestet werden soll / muss.
Ich habe das Gefühl, dass sowas sehr schwierig ist, im nachhinein reinzupflanzen, nicht nur wegen dem Aufwand, sondern auch weil man nicht wirklich weiss, was getestet werden soll und wann alles abgedeckt ist.

Anders sieht es bei einem Redesign einer Anwendung aus, dort kann man eher Unittests einbauen, ganz sicher beim neuen Code und dann ggf. noch die Integration mit dem bestehenden Code testen, der dann meistens dabei noch angepasst wird.

Hardcore-TDD?

“Hardcore-TDD”, also zuerst die Tests und erst danach den Produktivcode, oder eher locker mal den Code schreiben und am Schluss die Tests hinzufügen?

Ja, ich gebe es zu, das ist eine Streitfrage. Ehrlich gesagt verstehe ich aber nicht wieso :-).
Irgendwie habe ich das Gefühl das es Extreme gibt, um den Menschen überhaupt klar zu machen, das es so / oder dies und das besser ist, als das bisherige.
Mit dieser Vorgehensweise kann man die Leute zum Aufwachen bringen, sich das überhaupt mal anzusehen – auch bei Clean Code Developer / Clean Code schön zu sehen.

Wenn man vor den Kopf gestossen wird, ist das schon mal der erste Schritt. Der zweite Schritt ist dann, sich mit dem Extremen zu befassen und irgendwo seinen Stil einzuordnen. Ich finde es macht – abgesehen um Leute vor den Kopf zu stossen – überhaupt keinen Sinn, etwas ins Extreme zu treiben.

Immer zuerst den Test schreiben und erst dann den Produktivcode mag bei kleineren Projekten, oder eben solchen die sehr modular und für Tests optimiert aufgebaut sind, funktionieren.

Ich habe das selber auch schon probiert und es ist schon eine coole Erfahrung:

  1. Test schreiben
  2. Benötigte Klassen erstellen
  3. Kompilieren => kompiliert
  4. Test laufen lassen => schlägt fehl => rot
  5. Klassen ausimplementieren, nur das nötigste
  6. Test laufen lassen => läuft => grün

Es gäbe theoretisch noch einen Zwischenschritt, bei dem kompiliert wird, obwohl die Klassen noch nicht vorhanden sind, aber damit kann ich mich irgendwie nicht anfreunden.
Auf jeden Fall macht man sich damit Gedanken, wie man sein API benutzen möchte und modeliert dann die Klassen auch so aus,
zusätzlich wird im besten Fall nur das implementiert was die Tests erwarten, also bis sie grün sind.

So kann mit Leichtigkeit die Einhaltung von YAGNI beim Entwickeln eingehalten werden.

Meiner Erfahrung ist aber leider die, dass vielerorts eben schon Projekte bestehen, die nicht darauf optimiert sind, mit Unittests abgedeckt zu werden.
Sei das jetzt nachträglich oder für neue Features die dazukommen. Dort ist es echt schwierig und da können meistens nur sehr loose angedockte Zusatzbibliotheken getestet werden, also ein Greenfield-Projekt das dann in die bestehende Umgebung eingebunden wird.

Überall wo es möglich ist, nach TDD zu entwickeln, mache ich das jetzt auch – mehr oder weniger, aber nicht komplett im Extremen.

App Light-Theme

01.11.2009 02:27:00 | Lars Schmitt

Wenn man einer Anwendung, zu einem einheitlichen Aussehen verhelfen oder die Anwendung um eine Theming Fähigkeit erweitern möchte, dem hat Microsoft mit dem WPF-Framework einen starken Partner, an die Seite gestellt. Um dieses zu bewerkstelligen stehen nun 2 Möglichkeiten zur Verfügung.

  1. Design-Ressourcen
  2. hmmmmm… sagen wir mal Light-Theme

an dieser Stelle möchte ich heute, mal die zweite Möglichkeit etwas näher beleuchten.

 

Erst einmal etwas dazu, was die Light Variante eigentlich sein soll.

In der Light Variante, setzten wir die Properties, der einzelnen Steuerelemente, über die Setter Möglichkeiten der Style Klasse innerhalb der Datei App.xaml.

<Application x:Class="TestApp.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <Style TargetType="{x:Type Button}">
            <Setter Property="Background" Value="Black"/>
            <Setter Property="Foreground" Value="White"/>
        </Style>
    </Application.Resources>
</Application>

zb Durch diesen Code würden alle Buttons, die diese Properties nicht definiert , sowie auch keinen eigenen Style, definiert haben einen schwarzen Hintergrund und einen Weißen Vordergrund erhalten. Um das ganze, jetzt aber austauschbarer zu halten, ist es nicht sinnvoll den Style direkt in die App.xaml zu schreiben. Für diesen Anwedungsfall würde sich doch ein ResourceDictinary viel besser eignen, also ziehen wir den kompletten Style Tag mal in ein ResourceDictionary um und binden dieses anstatt des Styles in die App.xaml. Nach diesem ersten aufräumen, erhalten wir nun folgenden Code.

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style TargetType="{x:Type Button}">
        <Setter Property="Background" Value="Black"/>
        <Setter Property="Foreground" Value="White"/>
    </Style>
</ResourceDictionary>
 

<Application x:Class="TestApp.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Dictionary1.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

Durch diese Veränderungen hat sich der Code zwar etwas geändert, jedoch wurde am Verhalten nichts geändert. Wenn man sich seine Anwendung einmal startet, könnte einem auffallen, dass (wir bleiben mal bei unserem Button) manche Buttons immer noch in seinen default Farben erscheinen.

Das könnte zb daran liegen, dass diese Buttons einen eigenen Style definiert haben, zb für einen Trigger.

<Window x:Class="TestApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Button>
            <Button.Style>
                <Style>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Path=Foo}" Value="True">
                            <Setter Property="Button.ToolTip" Value="Foo ist True"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Button.Style>
        </Button>
    </Grid>
</Window>

An dieser Stelle ist das Style Property, bereits im Button definiert, also kann der Style aus der App.xaml nicht greifen. Jedoch mit einer kleineren Änderung am Code, lässt sich dieses Problem schnell beseitigen.

<Window x:Class="TestApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Button>
            <Button.Style>
                <Style BasedOn="{StaticResource {x:Type Button}}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Path=Foo}" Value="True">
                            <Setter Property="Button.ToolTip" Value="Foo ist True"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Button.Style>
        </Button>
    </Grid>
</Window>

nach diesen Änderungen, sollten nun endlich alle Controls, den im ResourceDictionary hinterlegten Styles entsprechen.

Solange man in seiner Anwendung, keine Unterstützung für Themes haben möchte, wäre man an dieser Stelle schon fertig, falls doch geht es noch ein wenig weiter.

Zum verändern des Themes, brauchen wir also eine Methode die die Kollektion Resources in der App.xaml verändert.

        ResourceDictionary rd = new ResourceDictionary();
        StreamReader sr = new StreamReader(string.Format("{0}/styles/{1}_styles.xaml", AppDomain.CurrentDomain.BaseDirectory, StyleName));
        rd = XamlReader.Load(sr.BaseStream) as ResourceDictionary;
 
        this.Resources.MergedDictionaries.Clear();
        //sicherheitsebene falls die externe Style Datei nicht komplett implementiert ist
        this.Resources.MergedDictionaries.Add(new ResourceDictionary { Source = new Uri("DefaultStyle.xaml", UriKind.Relative) });
        this.Resources.MergedDictionaries.Add(rd);

so Fertig, Anwendung starten und an dem neuen Theming Feature erfreuen, doch was ist das die Buttons mit den Triggern und eigenen Style verändern sich nicht.

 

Warum?

 

Wir benutzen zwar die BasedOn Eigenschaft, doch leider ist es per StaticResource eingebunden, es reagiert also nicht auf die Veränderungen der ResourceDicts.

Aber auch für diesen Problem gibt es eine Lösung, die Werte aus dem Style müssen doch nochmal aus den Style Implementierungen heraus, damit die Werte dann wieder als DynamicResource eingebunden werden können.

Resource1.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <SolidColorBrush x:Key="ButtonBackground" Color="Black"/>
</ResourceDictionary>

Resource2.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"                    
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style TargetType="{x:Type Button}">
        <Setter Property="Background" Value="{DynamicResource ButtonBackground}"/>
    </Style>
</ResourceDictionary>

inklusive der Zusammenführung in der App.xaml 

<Application x:Class="TestApp.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Resource1.xaml"/>
                <ResourceDictionary Source="Resource2.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

an dieser Stelle wäre es dann endlich vollbracht, die Anwendung kann nun mit verschiedenen Themes ausgeliefert werden.

WPF Forum | ASP.NET Forum | ASP.NET MVC Forum | Silverlight Forum | Windows Phone 7 Forum | SharePoint Forum | Dotnet Jobs | Dotnet Termine | Developer Blogs | Dotnet News

Das Team | Regeln | Impressum