In einem weiteren Artikel hab ich beschrieben, wie eine Silverlight DLL auch unter .NET/WPF verwendet werden kann. Dabei ist man allerdings auf die Verwendung von nur wenigen Namesspaces beschränkt. Wie ist es jedoch bei Entwicklung einer UI bis hin zu Custom Controls. Hier möchte ich mich auf die Entwicklung eines Custom Controls konzentrieren, da das für mich in einem besonderen Fokus steht.
Habe zunächst versucht die Testentwicklung unter Visual Studio 2010 und Silverlight 4 Beta durchzuführen. Zu deisem Zeitpunkt war eine RC des VS verfügbar, jedoch konnte man die Silverlight 4 Beta nur zum Studio Beta installieren. Gequält durch viel zu viele Abstürze des VS, vermutlich hervorgerufen durch die komplexere Projektstruktur mit Links zu Dateien in der “Solution” und Prokjekte, habe ich nun das Studio 2008 und SL 3 verwendet. Einfachere Projekt konnte ich in der Beta des Visual Studio allerdings anstandslos erstellen, bauen und debuggen.
Probleme und Lösungsvorschläge zum CrossDevelopment eines CustomControls:
Verknüpfte Dateien:
Reduziert man sich auf den Silverlight-Befehlssatz und umgeht unausweichliches mit einem CompilerSwitch (siehe Abschnitt Konstruktor), kann man dem WPF-Projekt die nötigen Quelldateien mit einem Link hinzufügen. Damit muss bei der Entwicklung nur noch an den Quelldateien des Silverlightprojektes gearbeitet werden. Das funktioniert bei cs-Dateien wunderbar, allerdings nicht bei XAML-ResourceDictionaries. Startet man die Anwendung und versucht eine Resource im Code zu laden wird eine Ausnahme ausgelöst, da die Resource nicht gefunden werden kann. Standardeinstellung für die “Build Action” der verlinkten Dateien ist wie bei einer tatsächlich vorliegenden Datei auf “Page” gesetzt. Aber auch andere Einstellungen wie Resource führen zu keinen Erfolg. Mögliche Lösung: In den Projekteinstellungen sich vor jedem Compile-Vorgang die aktuelle Datei kopieren. Dazu ein “Prebuild-Event Command” bei den Projekteinstellungen hinzufügen. Beispiel:
copy $(SolutionDir)CrossGaugeSLThemes3DSilverBrushes.xaml $(ProjectDir)Themes*.*
Werden C#-Quelldateien über eine Dateiverknüpfung dem Projekt hinzugefügt welche CompilerSwitches wie “‘if SILVERLIGHT” enthalten, ist Debuggen innerhalb dieser Datei nicht mehr möglich. Mögliche Lösung: Kopieren wie oben beschrieben.
Diese Lösung birgt aber eine große Gefahr, die einen Entwickler gerne in den Wahnsinn treiben. Beispiel: Silverlight-Projekt ist Master und WPF-Projekt ist Dateiempfänger aus Silverlight-Projekt. Entwickler editiert fälschlicherweiße Quelldatei im WPF-Projekt … bei der Generierung überschreibt der Kopierbefehl die geänderte Datei so sind die Änderungen verloren.
Konstruktor:
Damit ein Control sein Design lädt, muss im Konstruktor Metadaten überschrieben werden, zumindest bei WPF. Ausserdem muss das bei WPF in einem statischen Konstruktor erfolgen. Folgendes CodeSnippet zeigt wie man das Problem mit einem CompilerSwitch umgeht.
#if SILVERLIGHT
public CrossGauge()
{
this.DefaultStyleKey = typeof(CrossGauge);
}
#else
static CrossGauge()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(CrossGauge), new FrameworkPropertyMetadata(typeof(CrossGauge)));
}
#endif
Silverlight vs. WPF:
- keine DynmanicResources (SL)
- keine DrawingVisuals (SL)
- keine ableitbare Shape-Klasse (SL)
- viele mit “SecurityCritical” gekennzeichneten Methoden (SL)