2009-09-03 7 views
15

Ich konvertiere eine WPF-App in Silverlight.Benutzerdefinierte Form in Silverlight (Portierungs-App von WPF)

Die App enthält eine Klasse, die von Shape erbt. Sie überschreibt die DefiningGeometry-Eigenschaft, um ein Path-Objekt zurückzugeben. Die Silverlight Shape-Klasse verfügt jedoch nicht über eine DefinitionGeometry-Eigenschaft.

Lesen im Internet Ich habe andere mit dem gleichen Problem gefunden. Die Lösung scheint direkt von Control zu erben und die Content-Eigenschaft auf den Pfad zu setzen. Ich möchte aber auch meine Event-Handler behalten (MouseEnter, MouseLeave, GotFocus, LostFocus) und ich möchte, dass sie ihre Position behält und proportional zur restlichen Anwendung skaliert.

Ich bin hauptsächlich ein Back-End-Entwickler, also ist das nicht meine Stärke - ich würde es begrüßen, wenn mir jemand ein Beispiel geben könnte, wie das zu erreichen ist.

+4

Sie können mehr Antworten erhalten, wenn Sie die ursprüngliche Klasse veröffentlichen. Dann könnten andere es schnell für Sie umschreiben. Viel Glück. –

+0

Dies ist ein ungelöstes Problem in Silverlight Foren http://forums.silverlight.net/forums/p/39904/113634.aspx und sogar die Lösung der Unterklasse Form in Silverlight 4 (http://blogs.msdn.com/b /nickkamer/archive/2009/12/03/subclassing-shape-or-more-accurately-path.aspx) hilft nicht mit dem Eigenschaftsproblem von DefiningGeometry. Wir sollten eine Belohnung für eine Lösung dafür starten. – Alain

Antwort

16

Sie können keine Klasse erstellen, die auf dieselbe Weise funktioniert, da Silverlight das Erstellen von benutzerdefinierten Elementen aus der Basisklasse Shape nicht unterstützt.

Der Grund, warum es in Silveright nicht möglich ist, eine benutzerdefinierte Form zu erstellen, ist, dass Silverlight nicht die "visuelle Ebene" von WPF teilt. Wenn Sie vollständig verstehen wollen, warum das, was Sie versuchen, unmöglich ist, müssen Sie verstehen, wie sich Silverlight hier von WPF unterscheidet. (Und wenn Sie sich nicht kümmern, überspringen Sie die nächsten 2 Absätze.)

In WPF können Sie auf zwei völlig verschiedenen Ebenen arbeiten: die visuelle Ebene oder die Framework-Ebene. Die Dienste der visuellen Ebene werden von WindowsBase.dll und PresentationCore.dll bereitgestellt. Dies bietet grundlegende Rendering- und Eingabedienste. Wenn Sie jedoch Dinge wie Formatierung, Datenbindung, Layout, Templating usw. möchten, benötigen Sie die Framework-Services, die von PresentationFramework.dll zur Verfügung gestellt werden. Die Formtypen - Rectangle, Path usw. - sind alle Framework-Typen - sie stammen von FrameworkElement und unterstützen Datenbindung, Layout, Animation und so weiter. Aber sie sind auf der visuellen Ebene implementiert - wenn Sie einen der Shape Typen in Reflector oder ILDASM betrachten, werden sie alle die OnRender Methode überschreiben, und das ist, wo der Code, der die tatsächliche Form definiert, lebt. (OnRender ist eine visuelle Layer-Funktion.) Und weil die visuelle Ebene eine vollständig unterstützte und dokumentierte API ist, können Sie Ihre eigenen Formen in WPF schreiben - Sie können genau die gleiche Art von Code schreiben, wie Sie ihn finden integrierte Formklassen.

Silverlight macht diese visuelle Unterscheidung nicht möglich - in Silverlight ist WPFs visuelle Ebene im Wesentlichen in der Framework-Ebene zusammengebrochen.Wenn Sie sich also die Shape-Typen in Reflector oder ILDASM ansehen, sehen Sie, dass sie keine Methode OnRender enthalten und sie fast leer sind. Das liegt daran, dass in Silverlight die Formen alle Eigenarten sind - das Plugin hat eine spezielle Handhabung für Ellipse, Path und alle anderen Formen. Daher ist die Gruppe der Formen in Silverilght nicht erweiterbar. Es gibt keine OnRender Methode, die in Silverlight überschrieben werden kann. Sie können also Ihre eigene benutzerdefinierte Klasse, die von Shape in Silverlight abgeleitet ist, einfach nicht schreiben.

Also, entweder eine benutzerdefinierte Control oder UserControl wird der Weg sein, fürchte ich. Dies sollte jedoch die MouseEnter und MouseLeave nicht funktionieren. Haben Sie tatsächlich festgestellt, dass diese nicht funktionieren? Oder nehmen Sie einfach an, dass sie nicht funktionieren werden?

+0

+1 für Ihre Theorie zu wissen, vor allem für Paradigmen, die so neu sind. – Alain

+0

+1 ausgezeichnete Antwort – ColinE

+0

+1 für Erklärung, -1 zu Microsoft für total lahme Erweiterbarkeit! –

0

Was ist, wenn Sie Ihre bestehende Klasse behalten, nennen wir es CustomShape, wie es ist, dann von Control mit etwas wie CustomShapeContainer inhärent? CustomShapeContainer wäre im Grunde nur ein Wrapper um CustomShape. Sie könnten dann alle in CustomShapeContainer eingehenden Ereignisse direkt an CustomShape übergeben und dann das DefiningGeometry-Objekt der Shapes als Containers-Inhalt zurückgeben.

Auf den ersten Blick scheint dies der Weg des geringsten Widerstands zu sein.

0

Sie haben in Silverlight nicht die gleichen Namespaces. Silverlight XAML ist eine Teilmenge von WPF XAML und es gibt Assemblys, die nicht in Silvelright enthalten sind. Diese Technologien sind für verschiedene Arten von Lösungen gedacht.

Sie müssen möglicherweise neu beginnen. Wenn Sie jedoch das MVVM-Muster verwenden, hinter dem nur sehr wenig Code steckt, können Sie ViewModel, Model und Services möglicherweise erneut verwenden. Vielleicht wären Ressourcen, Stile in Ordnung, um "wie es ist" wiederzuverwenden. Aber die Aussicht: Neu anfangen.

0

Beginnend mit Silverlight 3 gibt es einen speziellen Typ von Shape namens Path, der eine Eigenschaft Data des Geometrietyps definiert. Sie sollten in der Lage sein, den ursprünglichen WPF-Code, der eine Geometrie erstellt hat, auf diese Data-Eigenschaft zu portieren.

+1

Ich weiß, dass der MSDN-Artikel, den Sie verlinken, anders vorschlägt, aber Path war seit Anfang an in Silverlight. –