Site logo
Site logo
Programmieren aus Leidenschaft
Programmieren aus Leidenschaft

Shapes Teil 1


Durch XAML-Deklarationen können in einem Fenster nicht nur Steuerelemente, sondern auf gleiche Art auch einfache geometrische Figuren erstellt werden. Dabei unterscheidet man zwei Gruppen von Figuren. Shapes, die von der Klasse UIElement abgeleitet sind und Geometry. Shapes haben den Vorteil, das sie sich selbst zeichen können, ohne dabei auf eine Helferklasse zurückgreifen zu müssen. Objekte vom Typ Geomerty können das nicht.

Dieses Kapitel beschäftigt sich mit der ersten Gruppe, den Shapes. Die Klasse Shape selbst ist eine abstrakte Klasse und somit nicht für die Darstellung von grafischen Objekten geeignet. Anders sieht es allerdings mit den Klassen aus, die von Shape abgeleitet sind. Ellipse, Line, Path, Polygon, Polyline, und Rectangle. Alle mehr oder weniger einfache geometrische Grundfiguren.
<StackPanel Orientation="Horizontal">
   <Rectangle Width="60" Height="30" Stroke="Yellow" StrokeThickness="1" Margin="5" Fill="Red" />
   <Rectangle Width="30" Height="60" Stroke="Black" StrokeThickness="1" Margin="5" />
   <Ellipse Width="40" Height="50" Stroke="Blue" Fill="Aquamarine" />
</StackPanel>
stacks_image_0AACFCCC-D12F-46EE-A647-09FD0AB45BED
Wichtig bei Shapes sind die Eigenschaften "Stroke" und "Fill", welche die Rahmenfarbe und die Füllfarbe bestimmen. Der Standardwert dieser Eigenschaften ist "null" und bewirkt, dass man ein Objekt nicht sieht, wenn nicht mindestens einer der Farbwerte gesetzt ist. Dieses Verhalten ist auch unabhängig von der Hintergrundfarbe des Fensters. Null bedeutet hier "nichts" und nicht etwa weiße Farbe.

Shapes bieten viele der Möglichkeiten, die auch Steuerelemente haben. Sie können transformiert werden und als Content für Steuerelemente dienen. Shapes haben selbst aber nicht die Möglichkeit einen Content aufzunehmen.
<Button Margin="5">
   <Rectangle Width="20" Height="40" Stroke="Black" StrokeThickness="1" Fill="Green">
   <Rectangle.LayoutTransform>
      <RotateTransform Angle="45" />
   </Rectangle.LayoutTransform>
   </Rectangle>
</Button>
stacks_image_022A360D-26FE-4336-9A6F-DBA101E7C42A
Natürlich sind die Anwendungsmöglichkeiten gering, sollte man Shapes tatsächlich nur neben- oder übereinander anordnen können. Da ein Shape aber keinen Content hat, scheint es auf den ersten Blick schwierig, Objekte ineinander darzustellen. Es ist auch nicht ohne weiteres möglich. Abhilfe schafft das Layoutelement "Canvas" (Leinwand), welches eine punktgenaue Positionierung von Objekten, relativ zu den Canvas Rändern ermöglicht. Natürlich kann man in einem Canvas auch normale Steuerelemente benutzen.
<Canvas>
   <Rectangle Width="50" Height="50" Stroke="Black" StrokeThickness="1" Fill="Red" Canvas.Top="20" Canvas.Left="20" />
   <Rectangle Width="50" Height="50" Stroke="Black" StrokeThickness="1" Fill="Blue" Canvas.Top="40" Canvas.Left="40" />
   <Rectangle Width="50" Height="50" Stroke="Black" StrokeThickness="1" Fill="Green" Canvas.Top="60" Canvas.Left="60" />
   <Button Canvas.Left="80" Canvas.Top="80" Width="75" Height="25">Hallo Welt</Button>
</Canvas>
stacks_image_90B6D258-0791-4DAC-B41F-7E39B15B7AB9
Ebenfalls ist es natürlich möglich, in einem Steuerelement einen Canvas als Content zu verwenden. Dabei sollte man aber unbedingt auf die Eigenschaften "HorizontalContentAlignment" und "VerticalContentAlignment" achten, da diese den Ursprung des Canvas beeinflussen.
<Button Margin="15" HorizontalContentAlignment="Left" VerticalContentAlignment="Top" Height="40">
   <Canvas>
      <Rectangle Width="10" Height="10" Stroke="Black" StrokeThickness="1" Fill="Red" Canvas.Top="5" Canvas.Left="5" />
      <Rectangle Width="10" Height="10" Stroke="Black" StrokeThickness="1" Fill="Blue" Canvas.Top="10" Canvas.Left="10" />
      <Rectangle Width="10" Height="10" Stroke="Black" StrokeThickness="1" Fill="Green" Canvas.Top="15" Canvas.Left="15" />
      <TextBlock Canvas.Top="8" Canvas.Left="35">Hallo Welt</TextBlock>
   </Canvas>
</Button>
stacks_image_F793FBF6-7D1C-422B-A61A-8F25EFE0A68B