-
ACHTUNG - NEUES BLOG
Ab sofort steht unter http://devtyr.norberteder.com mein neues Blog zur Verfügung. Dieses Blog wird nicht weiter betreut, bleibt aber erhalten. Neue Eintr%auml;ge erfolgen nur mehr im neuen Blog. Kommentare werden ebenfalls nicht mehr behandelt. Wer weiterhin meinen Einträgen und Aktivitäten folgen möchte, möge bitte RSS-Feeds, Verlinkungen etc. an die neue Location anpassen.
|
Anwendungen und Dokumente ultraschnell starten
10.01.08 - Tools, 3rd Party Tools Beitrag von Norbert Eder| | Lange Zeit habe ich mich persönlich ja gegen ein "Starthilfe"-Tool gewehrt. Dennoch ist mir immer wieder Launchy unter gekommen.
Nun läuft das Tool seit ein paar Wochen auf meinem Rechner und tut wunderbar seinen Dienst - und das in Rekordzeit. Anwendungen, Dokumente etc. können superschnell gestartet werden, durch Plugins ist es möglich eigene "Features" zu "implementieren". Einfach wunderbar. In der Tat ein Tool für Jedermann.
Beispiel Erweiterbarkeit
Für mich als Entwickler sind natürlich Inhalte aus dem MSDN interessant. Mit ein paar wenigen Einstellungen kann via Launchy direkt nach Links zu bestimmten MSDN-Einträgen gesucht werden.
Hierzu ist per rechter Maustaste das Kontextmenü zu öffnen und der Punkt Options zu wählen. Nun die Lasche Plugins und dort den Eintrag Weby wählen. Hier ist nun ein neuer Eintrag mit folgenden Einstellungen zu erstellen:
Name: msdn
Url: http://search.live.com/
Query: results.aspx?q=%s+site:msdn2.microsoft.com
Nach dem Speichern kann unter Launchy nun in der Suchleiste via Eingabe von msdn, gefolgt von der Tabulatortaste und dem Suchbegriff sofort via Live Search nach MSDN-Artikeln gesucht werden.
| | | 2 Kommentare
- 979 mal angesehen
| 0 Trackbacks
| Permalink | Trackback-URL |
Drei Kostenlose Microsoft Press Bücher
10.01.08 - .NET, ASP.NET, Silverlight, Datenverwaltung, Internet Beitrag von Norbert Eder| | Es gibt sie zwar schon länger, aber ich wurde erst kürzlich darauf aufmerksam. Microsoft bietet drei Bücher als E-Book kostenlos an:
- Introducing Microsoft LINQ
- Introducing Microsoft ASP.NET AJAX
- Introducing Microsoft Silverlight 1.0
Weitere Informationen sind hier zu finden.
| | | Kommentar hinzufügen
| 0 Trackbacks
| Permalink | Trackback-URL |
Visual Studio Templates erstellen
09.01.08 - .NET, Visual Studio Beitrag von Norbert Eder| | Einleitung
Visual Studio wird bereits mit jeder Menge Templates ausgeliefert, die es uns Entwickler ungemein erleichtern, Projekte oder einzelne Dateien zu erstellen. Ohne diese Templates wäre der Aufwand, ein Projekt einzurichten wohl ein wesentlich größerer Bestandteil unserer Arbeit. Dieser Artikel zeigt, wie schnell und einfach Templates für einzelne Dateien eingerichtet werden können, um sich zukünftig einige Arbeitsschritte zu ersparen.
Wann lohnt sich ein Template?
Templates sind immer dann sinnvoll, wenn im gleichen Projekt (oder auch unterschiedlichen Projekten) häufig dasselbe Grundgerüst eingefügt werden muss. Ein Beispiel.
In vielen Anwendungen wird ein Logging-Framework verwendet, um Informationen während der Laufzeit zu erfassen (Statusmeldungen, Debug-Informationen, Fehlermeldungen usw.). Um in eine Klasse mit inkludiertem Logger zu erhalten müssen einige Schritte vollführt werden:
- Neue Klasse anlegen
- Referenz auf Logging-Framework setzen
- Logger instanzieren
Mit der Anzahl der erstellten Klassen, welche den besagten Logger nutzen, steigt auch der dafür benötigte Aufwand. Das mag vielleicht auf den ersten Blick als gering abgetan werden. Nehmen wir für die genannten Schritte eine notwendige Zeit von ca. 20 Sekunden an erscheint dies wirklich gering zu sein. Selbst kleinere Projekte inkludieren recht schnell 100 Klassen (die für ein Logging relevant sind). Der Aufwand dafür läge nun schon bei über 30 Minuten. 30 Minuten, die man für wichtigere Aufgaben verwenden kann, als eine Klasse inklusive Logger zu erstellen (zumal immer wiederkehrende Aufgaben ermüdend und nervig sind). Ein Template hierfür rechnet sich also. Analysiert man seine tägliche Arbeit, ergeben sich sehr viele Möglichkeiten, die die Erstellung eines Templates rechtfertigen würden.
Basiswissen
Templates werden von Visual Studio verwendet, um sogenannte Vorlagen zur Verfügung zu stellen. Diese Vorlagen definieren, wie vordefinierte Projekte (ProjectTemplates) und einzelne Dateien (ItemTemplates) auszusehen haben. Die Standard-Templates für die beiden genannten Typen sind in folgenden Verzeichnissen zu finden:
ProjectTemplates
<programs directory>\Common7\IDE\ProjectTemplates
ItemTemplates
<programs directory>\Common7\IDE\ItemTemplates
Um die Standard-Templates von den eigenen zu trennen, befinden sich in den Eigenen Dateien des jeweiligen Benutzers ebenfalls entsprechende Verzeichnisse. Im Falle von Visual Studio 2008:
ProjectTemplates
<Eigene Dateien>\Visual Studio 2008\Templates\ProjectTemplates
ItemTemplates
<Eigene Dateien>\Visual Studio 2008\Templates\ItemTemplates
Wird eine andere Version verwendet, ändert sich entsprechend der Pfad (für Visual Studio 2005 wird aus 2008 2005 usw.).
Jedes dieser Templates ist in einer ZIP-Datei abgelegt, welche in einen Cache-Ordner (ProjectTemplatesCache bzw. ItemTemplatesCache) entpackt und gelesen werden. Dies kann auch ein Grund sein, dass Änderungen an einem Template nicht sofort in Visual Studio verfügbar sind.
In jeder Zip-Datei muss eine Datei mit der Endung vstemplate vorhanden sein. Diese enthält die Metadaten zum jeweiligen Template. Ebenfalls vorhanden sein müssen die in den Metadaten referenzierten Dateien.
Ein konkretes Beispiel
Mitunter kommt es vor, dass nicht die von .NET bereit gestellte Anwendungs-Konfiguration verwendet wird, sondern eine eigene Lösung, die meist in allen Projekten von gleichem Aufbau ist. Die einzelnen Einstellungen werden in einer XML-Datei abgelegt. Zu Beginn muss die Vorlage erstellt werden. Dafür wird das Grundgerüst der Konfigurationsdatei erstellt.
ConfigurationFile.xml
<?xml version="1.0"?>
<AppConfiguration>
<ReferencedConfigurations>
</ReferencedConfigurations>
<Commands>
</Commands>
<MiscSettings>
</MiscSettings>
</AppConfiguration>
Bei Verwendung dieses Templates wird eine Datei mit oben beschriebenen Inhalt angezeigt.
Im nächsten Schritt müssen die Metadaten angegeben werden. Nur mit diesen Angaben ist Visual Studio in der Lage, das erstellte Template zu verwalten und bereit zu stellen.
ConfigurationFile.vstemplate
<?xml version="1.0" encoding="utf-8"?>
<VSTemplate
Version="3.0.0"
Type="Item"
xmlns="http://schemas.microsoft.com/developer/vstemplate/2005">
<TemplateData>
<Name>Custom Configuration File</Name>
<Icon></Icon>
<Description>
Creates a custom configuration file
</Description>
<ProjectType>CSharp</ProjectType>
<ProvideDefaultName>true</ProvideDefaultName>
<DefaultName>ConfigurationFile.xml</DefaultName>
</TemplateData>
<TemplateContent>
<ProjectItem
ReplaceParameters="true"
TargetFileName="$fileinputname$.xml">
ConfigurationFile.xml
</ProjectItem>
</TemplateContent>
</VSTemplate>
Wie üblich, handelt es sich auch dabei um eine XML-Datei, die grundsätzlich recht einfach aufgebaut ist. Das Root-Element wird immer durch ein VSTemplate-Tag dargestellt. Danach folgen die Elemente TemplateData und TemplateContent. Ersteres beschreibt die grundlegenden Eigenschaften des Templates. Dies betrifft den Namen, die Beschreibung, für welchen Projekt-Typ dieses Template verwendet werden kann und weitere Angaben (die sich bei einem ProjectTemplate teilweise unterscheiden). Im Bereich TemplateContent wird nun definiert, welche Dateien, Referenzen etc. verwendet werden. Auch hier gibt es einen Unterschied zwischen ProjectTemplate und ItemTemplate.
Wurden beide Dateien angelegt, sind diese in eine Zip-Datei zu packen und in das jeweilige Verzeichnis zu kopieren. Nach einem Neustart von Visual Studio sollte dieses Template nun zur Verfügung stehen.
Zu beachten ist, dass es in den einzelnen Template-Verzeichnissen Unterordner zu den jeweiligen Sprachen gibt. Darunter kann wird eine weitere Verzeichnisstruktur abgebildet, die in den „New Item“-Wizard übernommen wird. Somit ist es möglich, eigene Templates nach Aufgabengebiet zu gruppieren.
Fazit
An diesem Beispiel war gut zu sehen, dass es sehr einfach ist, ein eigenes Template zu erstellen. Natürlich stehen weitere Möglichkeiten zur Verfügung, beispielsweise die Angabe und Verwendung von Parametern, Bedingungen usw. Es lohnt sich ein Blick in die Template Referenz, um eine Übersicht und Beschreibung aller möglichen Settings zu erhalten.
Referenzen
Visual Studio: Anpassung Class Template
Visual Studio Template Reference
| | | Kommentar hinzufügen
| 0 Trackbacks
| Permalink | Trackback-URL |
Dezember 2007 im Rückblick
08.01.08 - Blog-Intern Beitrag von Norbert Eder
5. Ausgabe .NET BlogBook - Gewinne ein VSone-Ticket
07.01.08 - .NET, Grundlagen, Base Framework, WPF, ASP.NET, Silverlight, Mobile Devices, Datenverwaltung, Visual Studio Beitrag von Norbert Eder| | Die nunmehr fünfte Ausgabe des .NET BlogBooks ist erschienen.
Die aktuelle Ausgabe wurde vor allem in den Bereichen Windows Presentation Foundation, C# 3.0 und Tools erweitert. Auch viele andere Bereiche profitieren von neuen Einträgen. Insgesamt bietet die fünfte Ausgabe nun knapp 320 Seiten Inhalte, um 40 mehr als Ausgabe vier.
Aber nicht nur beim Inhalt hat sich etwas getan. Nein, auch dieses Mal gibt es wieder ein Gewinnspiel. Zu gewinnen gibt es ein Ticket der VSone. Also ran ans Zeug! Downloaden, auf Seite 3 die Teilnahmebedingungen lesen und vielleicht gewinnen.
Link: .NET BlogBook Projektseite
PS: Zusammen mit der fünften Ausgabe feiert das .NET BlogBook nun auch schon das erste überstandene Jahr - und das durchaus erfolgreich!
| | | 6 Kommentare
- 919 mal angesehen
| 1 Trackbacks
| Permalink | Trackback-URL |
Bringt die IT nur Fortschritt oder ergeben sich daraus zusätzliche Probleme?
04.01.08 - Kunterbunt Beitrag von Norbert Eder| | Diese Frage ist mir in der letzten Zeit immer wieder durch den Kopf gegangen. Daher habe ich mich entschlossen, ein paar Zeilen dazu als Grundlage für eine Diskussion zu verfassen.
Es ist schon wahr. Durch die IT-Industrie gab es in den letzten Jahren einen gewaltigen Fortschritt - oder war alles vielleicht doch so, wie bei den Transformers? Hier wurde die Technologie ja quasi von Megatron dem Leader der Deceptions "geklaut".
Wie es auch immer war und ist, es hat uns Fortschritt gebracht und somit sehr viele neue Möglichkeiten eröffnet. Doch alles hat auch seine Nachteile. Ich möchte hier auch nicht groß das Thema Umweltverschmutzung und Erderwärmung ansprechen. Dieses Thema wurde ohnehin ohne Ende durch die Medien gezerrt und es wird auch zukünftig noch im großen Stil (wie in den alten Western) durch sämtliche Städte (Medien) geschliffen werden. Anyway.
Das worauf ich hinaus möchte betrifft vielmehr die Frage, ob wir uns die Technik zukünftig noch leisten werden können.
Den Westen betreffend: Heute ist mindestens ein Rechner pro Haushalt Standard. Jeder besitzt mindestens ein Handy. Ja, sogar die 5jährigen laufen schon mit Handies durch die Gegend. iPods, Konsolen (tragbar oder nicht), Fernseher in allen möglichen Größen, Receiver, DVD, HD-DVD/Bluray, die entsprechenden Receiver, Navigationsgeräte, Handhelds und vieles mehr. In den meisten Haushalten ist etwas (teilweise sogar vieles) davon zu finden.
Neue Entwicklungen werden gemacht, "alte" Geräte müssen natürlich ausgetauscht werden, um mit der Zeit zu gehen. Der typische Standard ist so hoch wie niemals zuvor. Doch dies ist noch nicht genug. Nehmen wir uns die Software vor. Es ist usus, am Rechner eine Firewall zu haben (und ja, die wirklich guten sind dann doch kostenpflichtig), einen Virenschutz und wer weiß was sonst noch alles. Das kostet alles Geld und belastet die Geldbörse. Auch wenn es nur 49 Euro pro Jahr sind, es läppert sich zusammen.
Alles halb so schlimm? Nun, wenn ich die Ausgaben für Handy, Subscriptions etc. zusammenrechne und mit denen der älteren Generation vergleiche wird der Unterschied sehr schnell deutlich. Es klafft ein Unterschied von teilweise bis zu mehreren hundert Euro .. pro Monat. Sollte uns das nicht zu denken geben?
Dafür sind auch die Gehälter höher als früher! Ja, das sind sie. Angepasst um die jährliche Inflation (oder höher, wenn gut verhandelt). Und die Inflation inkludiert diese neuen Gegebenheiten natürlich nicht. Wie denn auch. Natürlich werden die Warenkörbe, auf deren Basis die Inflation berechnet wird, angepasst. Aber fallen hier Subscriptions hinein? Fällt hier hinein, dass mittlerweile schon jeder ein Handy haben muss, weil ein gewisser Zwang durch die Gesellschaft gegeben ist? Nein, das tut es nicht.
Mir ist natürlich klar, dass jedes Unternehmen Geld verdienen muss (freie Marktwirtschaft -> Gewinnmaximierung), dennoch nimmt dieser (teilweise aufgedrückte) Konsumwahn Ausmaße an, die zwangsweise zu einer Teilung in eine Mehrklassengesellschaft führen müssen. Je mehr Dienste, neue Entwicklungen und zusätzliche Geräte, desto weniger Personen können sich wirklich alles leisten. Und somit ist derjenige, der mehrmals täglich in seinen Geldbeutel blicken muss, ob er in diesem Monat überhaupt durch kommt, als "Blödmann" abgestempelt.
Lösung? Nein, ich habe keine Lösung. Ich weiß nur, dass dies sicherlich nicht ewig so weitergehen kann. Irgendwann - und das wird wohl wieder einmal mit der IT-Branche beginnen - gibt es das nächste Kabumm und dann wird ein Umdenken stattfinden müssen. Sowohl auf die Leistbarkeit hin, als auch bezüglich vieler anderer Bereiche. Das Gesamtkonzept muss angepasst werden, einen anderen Weg wird es nicht geben. Just my 2 cents.
| | | 2 Kommentare
- 763 mal angesehen
| 0 Trackbacks
| Permalink | Trackback-URL |
Foto/Grafik-Manipulationen einfach und schnell - Beispiel Sepia
03.01.08 - .NET, Grundlagen, Base Framework, Allerlei Beitrag von Norbert Eder| | In vielen Anwendungen werden Grafiken jeglicher Art angezeigt. Und manches Mal, wollen diese auch manipuliert werden. Die Gründe sind hier manigfaltig. In meinem Fall mussten Fotos sepia-färbig dargestellt werden. Mit Hilfe der Klasse ColorMatrix aus dem Namespace System.Drawing.Imaging (System.Drawing.dll) läßt sich dies in wenigen Sekunden bewerkstelligen.
Doch was genau macht die Klasse ColorMatrix? Hier die treffende Beschreibung aus der MSDN:
Defines a 5 x 5 matrix that contains the coordinates for the RGBA space. Several methods of the ImageAttributes class adjust image colors by using a color matrix.
Anmerkung: A ist der Alpha-Kanal, welcher die Transparenz einer Farbe beschreibt.
Sepia selbst ist nichts anderes, als die Darstellung einer Grafik/eines Bildes in Brauntönen, anstatt in Grau-Schattierungen.
Nachfolgend wird nun die Matrix für unsere Sepia-Darstellung definiert (Nachschlagen, Grafiker fragen, alles ist erlaubt):
private ColorMatrix GetSepiaMatrix()
{
return new ColorMatrix(new float[][]
{
new float[] {0.393f, 0.349f, 0.272f, 0, 0},
new float[] {0.769f, 0.686f, 0.534f, 0, 0},
new float[] {0.189f, 0.168f, 0.131f, 0, 0},
new float[] { 0, 0, 0, 1, 0},
new float[] { 0, 0, 0, 0, 1}
});
}
Nun muss die Matrix nur mehr verwendet werden. Hier der Code aus dem Button-Click-Event meiner kleinen Demo-Anwendung:
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "JPEG-Files:*.jpg";
ofd.DefaultExt = ".jpg";
ofd.Title = "Open JPG File";
if (ofd.ShowDialog() == DialogResult.OK)
{
if (OriginalPicture.Image != null)
OriginalPicture.Image.Dispose();
if (SepiaPicture.Image != null)
SepiaPicture.Image.Dispose();
Image img1 = Image.FromFile(ofd.FileName);
Image img2 = Image.FromFile(ofd.FileName);
OriginalPicture.Image = img1;
ImageAttributes imageAttrs = new ImageAttributes();
imageAttrs.SetColorMatrix(GetSepiaMatrix());
using (Graphics g = Graphics.FromImage(img2))
{
g.DrawImage(
img2,
new Rectangle(0, 0, img2.Width, img2.Height),
0, 0, img2.Width, img2.Height,
GraphicsUnit.Pixel, imageAttrs);
}
SepiaPicture.Image = img2;
}
Anmerkungen: OriginalPicture und SepiaPicture sind beide vom Typ PictureBox.
Und so kann ein mögliches Ergebnis ausssehen:
PS: Dieses Foto wurde übrigens 2005 von mir in Venedig aufgenommen. Schon eine recht nette Stadt muss ich sagen, wenn es auch ständig nach Fisch riecht ;-)
| | | Kommentar hinzufügen
| 0 Trackbacks
| Permalink | Trackback-URL |
OT: SAT-Kabel verlegen - jemand eine Idee?
03.01.08 - Blog-Intern, Kunterbunt Beitrag von Norbert Eder| | Fernseher und Playstation sind ein Hit. Jedoch fehlt noch eine Kleinigkeit, damit das alles wirklich Hand und Fuß hat bzw. auch einigermaßen gut aussieht.
Der Übeltäter ist auf nachfolgendem Foto zu sehen:
Es ist schön zu erkennen, dass das dazugehörige SAT-Kabel quasi durch den gesamten Raum läuft und zwar etwas ... aufdringlich. Mir fehlen nun die Ideen, wie man das sauber verstecken kann.
Grundsätzlich würde es die Möglichkeit eines dünneren Kabels geben, von welchem mir jedoch abgeraten wurde. Es sind immerhin doch ca. 5 Meter und angeblich wäre der Signalverlust zu hoch. Weiters kann ich das Kabel nicht so einfach hinter die Sesselleiste klemmen, da diese erstens verpickt ist und zweitens keinen Hohlraum besitzt.
Hat hier ein "Tim Taylor" vielleicht einen Tipp für mich?
| | | 11 Kommentare
- 1049 mal angesehen
| 0 Trackbacks
| Permalink | Trackback-URL |
WPF Teil 3: Das Softwaredesign will gut überlegt sein
02.01.08 - .NET, Grundlagen, WPF Beitrag von Norbert Eder| | Bisherige Teile:
WPF Teil 1: Die Windows Presentation Foundation aus der Sicht eines Unternehmens
WPF Teil 2: Windows Presentation Foundation oder doch lieber Windows Forms?
Im letzten Beitrag wurde die Frage geklärt, wann denn eine Umsetzung mit Hilfe der Windows Presentation Foundation als sinnvoll erscheint und in welchen Fällen dann doch zu den herkömmlichen Windows Forms gegriffen werden soll. Ist eine Entscheidung zugunsten der WPF gefallen, müssen einige Vorarbeiten erledigt werden. Unter anderem betrifft dies das Design der Software selbst. Einige Verhaltensweisen sind dann doch unterschiedlich, was sich unter anderem auch im Softwaredesign auswirkt. Nachfolgend werden diesbezüglich einige Varianten vorgestellt als auch einige allgemeine Punkte behandelt.
Bietet die WPF bereits ein entsprechendes Konzept?
In die Windows Presentation Foundation wurde einiges an Funktionalität und viele neue Konzepte hineingepackt. Auch für das Softwaredesign wurde etwas getan. So ist es wichtig, Businesslogik von der Darstellung zu trennen. Dies wird mit Hilfe der WPF-Commands ermöglicht. Wie der verlinkte Artikel zeigt, stehen mehrere Varianten zur Verfügung. Mal enger mit der UI gekoppelt, mal davon losgelöst.
Für kleinere Projekte mag dies durchaus eine gute Wahl darstellen. Für größere Projekte (beispielsweise von Anwendungen mit einigen Mannmonaten Aufwand) meine ich, dass dieses Konzept nicht vollkommen taugt. Hier bedarf es einer größeren und besseren Lösung.
Das Model-View ViewModel Pattern
Eine wesentlich bessere Lösung wird uns hier mit dem Model-View ViewModel in die Hand gelegt. Es ist dies eine Variante des Model-View-Controller Patterns.
Dies sieht auf den ersten Blick möglicherweise etwas verwirrend aus, tatsächlich gestaltet sich die Verwendung jedoch nicht schwierig. Im Gegensatz zum MVC wird der Controller hier mit einer ModelView ausgetauscht (wobei im Hintergrund weiterhin auch ein Controller seinen Dienst tun kann). Die ModelView besitzt eine enge Kopplung zur View -> DataBinding. Dadurch kann die UI auf sehr einfache Weise aktualisiert werden. Diese enge Bindung muss jedoch nicht an das Model weitergegeben werden. Letzteres hält die einzelnen Entities.
Durch die Trennung in diese einzelnen Bestandteile ist es nun möglich, Daten- und Geschäftsklassen vom User Interface zu trennen. Der Vorteil besteht darin, dass die gesamte Anwendungsarchitektur dadurch flexibler, austauschbarer und vor allem testbarer wird.
Zu diesem Thema gibt es eine Serie von Dan Crevier welche ich dem Leser nicht vorenthalten möchte:
DataModel-View-ViewModel pattern: 1
DataModel-View-ViewModel pattern: 2
DM-V-VM part 3: A sample DataModel
DM-V-VM part 4: Unit testing the DataModel
DM-V-VM part 5: Commands
DM-V-VM part 6: Revisiting the data model
DM-V-VM part 7: Encapsulating commands
DM-V-VM part 8: View Models
Ebenfalls sehr lesenswert ist der Artikel Tales from the Smart Client von John Gossman.
Weitere Patterns
Im WPF-Umfeld stehen derzeit nicht mehr wirklich andere Patterns für die Kommunikation zwischen dem User Interface und den darunter liegenden Schichten zur Verfügung. Natürlich muss hier erwähnt werden, dass selbst das MVVM Anpassungen erfahren kann und im Laufe der Entwicklung an einer eigenen Lösung auch erfahren wird.
Es empfiehlt sich jedoch auf jeden Fall, alle Anforderungen zu definieren und daraus weitere mögliche Patterns, die innerhalb des MVVMs zum Zuge kommen abzuleiten.
Fazit
Immer, wenn neue Technologien oder Konzepte ins Spiel kommen, müssen neue Mittel und Wege gefunden werden, ein Projekt erfolgreich abzuschließen. Das MVVM ist ein erster Schritt in die richtige Richtung. Mit Fortbestand der WPF werden weitere Lösungen, Abwandlungen des MVVMs und weitere Verbesserungen auf uns Entwickler zukommen.
Grundsätzlich empfehle ich, das erwähnte Pattern in kleinem Rahmen zu testen und einen kleinen Prototyp zu entwickeln, um ein erstes Gefühl zu bekommen. Darauf aufbauend können anschließend die ersten ernsthaften Anwendungen entwickelt werden.
Tipp: Setzen Sie sich mit den Eigenheiten der WPF auseinander, um vor unliebsamen Überraschungen geschützt zu sein. Gerade wenn unbekannte Patterns das erste Mal eingesetzt werden, kann es sehr leicht zu Designfehlern kommen, die im weiteren Zuge größere Umstellungen/Refactorings notwendig machen.
| | | 3 Kommentare
- 1094 mal angesehen
| 0 Trackbacks
| Permalink | Trackback-URL |
WPF: RoutedCommand, RoutedUICommand, ICommand und Commands im Allgemeinen - Eine Einführung
02.01.08 - .NET, Grundlagen, WPF Beitrag von Norbert Eder| | Einige mögen bereits wissen, dass unter der Windows Presentation Foundation die Möglichkeit besteht, Commands zu verwenden. Für andere mag es neu sein. Wem ein Command gar nichts sagt, der möge sich meinen Beitrag Patterns: Command Pattern zuvor zu Gemüte führen.
Das Command-System wurde in die Windows Presentation Foundation integriert, um durchzuführende Aufgaben/Tasks besser vom User Interface (Oberfläche) zu trennen.
Warum UI von Aufgaben trennen
Ein oft geschilderter Vorteil der WPF ist, dass das grafische Design nicht zwingend vom Entwickler gemacht werden muss. So kann hier in der Tat ein Designer Hand anlegen (jedoch muss er etwas von XAML verstehen). Das ist jedoch nicht der Punkt, auf den ich hinaus möchte.
Ein Grundsatz der Softwareentwicklung ist es, stabile und robuste Software zu bauen. Dazu muss natürlich getestet werden. Manuelle Tests, die alles abdecken sind aber einer bestimmten Projektgröße kaum durchzuführen. Automatisierte Tests müssen her. Mit Hilfe von Unit Tests können nun Teile der Anwendung getestet werden. Dies funktioniert jedoch nur dann, wenn diese Teile vom grafischen Aufbau komplett getrennt sind. Sinnvoller Weise werden nun sämtliche Aufgaben von der UI getrennt und werden/bleiben so testbar.
Wie kann die WPF hier helfen?
Mit Hilfe der WPF Commands muss hier kein großer Aufwand betrieben werden, um obiges Ziel auch tatsächlich zu erreichen. Nun gibt es jedoch zwei abzudeckende Möglichkeiten:
- Commands müssen das UI aktualisieren
- Commands können komplett frei von allen UI-Einflüssen ausgeführt werden
Muss der Command mit der Oberfläche interagieren, sind RoutedUICommands genau der richtige Ansatz. Im zweiten Fall ist das Interface ICommand zu implementieren.
Bezüglich der RoutedUICommands ist es nun so, dass durch die WPF bereits einige fertige Implementierungen vorhanden sind:
Der Vorteil liegt darin, dass diese Commands sehr einfach an UIElemente gebunden und ausgeführt werden können. Hier ein kleines (unvollständiges) Beispiel zur Veranschaulichung:
<UserControl.CommandBindings>
<CommandBinding
Command="MediaCommands.Play"
CanExecute="OnQueryExecute"
Executed="Execute"/>
</UserControl.CommandBindings>
<StackPanel Grid.Row="2" Orientation="Horizontal">
<Button
Command="MediaCommands.Play"
Content="{Binding RelativeSource={RelativeSource Self},
Path=Command.Text}" />
</StackPanel>
Da diese Commands jedoch ein spezifisches Verhalten anbieten, welches nicht immer benötigt wird, ist es mitunter notwendig, eigene Commands zu implementieren, um die gewünschte Funktionalität zu erhalten.
Eigene Commands via ICommand implementieren
Müssen eigene Funktionalitäten als Command abgebildet werden, kann dies mit Hilfe einer Implementierung des ICommand-Interfaces passieren. Dieses Interface schreibt zwei Methoden vor und ein Event vor:
- CanExecute
- Execute
- CanExecuteChanged
Ein simpler Beispielcommand, welcher ein bestimmtes Objekt entgegeben nimmt und dieses manipuliert, könnte wie folgt aussehen:
public class MySaveCommand : ICommand
{
#region ICommand Members
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
if (parameter is EasySum)
{
EasySum es = (EasySum)parameter;
es.Result = es.Summand1 + es.Summand2;
}
}
#endregion
}
Eine weitere - und vor allem übliche - Möglichkeit besteht darin, einen RoutedCommand zu erstellen.
RoutedCommand erstellen
Mit Hilfe von RoutedCommands ist es sehr einfach, einen Command für das User Interface zu erstellen. Dazu benötigt es nicht sehr viel. Das nachfolgende Beispiel zeigt, wie anhand eines RoutedCommands die Hintergrundfarbe eines Panels verändert werden kann.
Hierzu muss unser neuer Command definiert werden:
public static RoutedCommand ChangeBackgroundCommand = new RoutedCommand();
Des weiteren müssen zwei Eventhandler implementiert werden. Zum einen für das CanExecute-Event und zum anderen für das Executed-Event.
private void ChangeBackgroundCommandCanExecute(
object sender, CanExecuteRoutedEventArgs e)
{
if (sender is Panel)
e.CanExecute = true;
else
e.CanExecute = false;
}
private void ChangeBackgroundCommandExecuted(
object sender, ExecutedRoutedEventArgs e)
{
Panel target = e.Source as Panel;
if (target != null)
{
if (target.Background == Brushes.AliceBlue)
{
target.Background = Brushes.LemonChiffon;
}
else
{
target.Background = Brushes.AliceBlue;
}
}
}
Im Eventhandler für das CanExecute-Event überprüfen wir lediglich, ob das übergebene UIElement auch tatsächlich ein Panel ist. Ist dem so, lassen wir eine Manipulation der Hintergrundfarbe zu. Andernfalls wird eine Ausführung des Commands verwehrt.
Im Eventhandler für das Executed-Event wird dann die Hintergrundfarbe geändert bzw. wieder auf die Ursprungsfarbe zurück gestellt.
Damit der Command nun auch verwendet werden kann, muss ein CommandBinding erstellt werden:
<StackPanel Name="MyStackPanel"
Background="AliceBlue"
Focusable="True">
<StackPanel.CommandBindings>
<CommandBinding
Command="{x:Static custom:Window1.ChangeBackgroundCommand}"
Executed="ChangeBackgroundCommandExecuted"
CanExecute="ChangeBackgroundCommandCanExecute"/>
</StackPanel.CommandBindings>
<Label>A StackPanel</Label>
<Button Command="{x:Static custom:Window1.ChangeBackgroundCommand}"
CommandParameter="ButtonOne"
CommandTarget="{Binding ElementName=MyStackPanel}"
Content="Change Background" />
</StackPanel>
Wie zu sehen ist, wird hier der aufzurufende Command definiert, als auch die beiden Eventhandler, die bereits implementiert wurden. custom definiert hier lediglich einen eigenen Namespace.
Das CommandBinding ist an einem StackPanel definiert, welches ein Label und einen Button enthält, welcher dann schlussendlich den Command auslöst.
Fazit
Dieser Artikel hat das der WPF zugrunde liegende Konzept der Commands vorgestellt und eine kleine Übersicht inklusive einiger Beispiele gegeben. Ebenso wurden die Unterschiede erläutert. Damit sollte nun jeder angehende WPF-Entwickler das notwendigste Wissen mitbringen, um eigene Commands zu entwickeln und diese in seinen Anwendungen einzusetzen. Natürlich wird es durchaus noch notwendig sein, das eine oder andere nachzulesen. Der Start sollte damit allerdings gemacht sein.
| | | Kommentar hinzufügen
| 2 Trackbacks
| Permalink | Trackback-URL | Zurück Weiter
|
|
|
|
|
|
|