Artikel

August 2006 | Artikel

Spezialeffekte

(Link zum Artikel: http://www.it-republik.de/dotnet/artikel/0878)

Textdarstellung mit der Windows Presentation Foundation

Text: von Dirk Frischalowski
  • Teilen
  • kommentieren
  • empfehlen
  • Bookmark and Share
Die im Grunde harmlose Ausgabe von Text hat es bei WPF bzw. XAML in sich, da es sehr viele Möglichkeiten gibt Text anzuordnen und mit „Spezialeffekten“ auszustatten. In dieser Folge der WFP-Serie dreht sich alles um die Ausgabe von Text.

Eine kleine Formalität vorweg: Mitte Juni entschied man sich bei Microsoft den Namen WinFX zu streichen und das, was bis dahin unter WinFX zusammgefasst wurde, zusammen mit dem .NET Framework 2.0 zum „.NET Framework 3.0“ zu machen. Außerdem gibt es kein WinFX SDK mehr, sondern ein Windows SDK, zu dem auch das bisherige .NET Framework SDK gehört. Aus der WinFX-Serie wird ab dieser Ausgabe die WPF-Serie, was sie im Grunde schon immer war - mehr ändert sich für Sie nicht. Inzwischen gibt es die Juni-CTP des Windows SDKs. Dieses arbeitet aber nicht mit der Beta 2 von Windows Vista zusammen, sondern benötigt schon eine aktuellere Version. Kleine Änderungen befinden sich in der Definition von Styles und NavigationWindows. XAMLPad wurde um den Visual Tree Explorer erweitert (Punkt 1 in Abbildung 1) - er stellt die Beziehungen der Komponenten in der Hierarchie grafisch dar und zeigt über ein weiteres Fenster, den Property Tree Explorer (Punkt 2 in Abbildung 1), die Eigenschaften des aktuell ausgewählten Elements an.

Mehr zu den Neuerungen in der Juni-CTP erfahren Sie über die Links und Blogs unter [1] und [2]. Von den Firmen Infragistics und Software FX können unter [3] die Komponenten DataPresenter und ChartFX geladen werden, welche bereits die neuen Möglichkeiten der WPF ausreizen. Von Mobiform ist unter [4] ein Update von Aurora, einem fortschrittlichen XAML-Designer, verfügbar.
Installationshürden
Sollte sich die (De)Installation einer neuen Version von WinFX nicht durchführen lassen, kann dies gleich mehrere Gründe haben. Auf dem Rechner des Autors ließ sich seit über einem Jahr eine alte Version von WinFX problemlos deinstallieren und die neue einspielen. Jetzt kommen sich allerdings die Setup-Programme doch langsam in die Quere. Bei Fehlern wird in der Regel eine Meldung angezeigt, die besagt, dass (irgendwelche) älteren Komponenten nicht korrekt deinstalliert wurden und somit die neue Version nicht installiert werden kann. Eine Lösung ist die Reparatur der alten Version und der erneute Versuch diese zu deinstallieren. Eine für die Zukunft sinnvolle Lösung ist die Installation unter VMWare oder Virtual PC bzw. auf einem jeweils nagelneuen System. Eventuell hilft es noch, die Komponenten einzeln zu deinstallieren [6] - dazu wechselt man in das Verzeichnis ..\Windows\WinFX bzw. jetzt nach ..\Windows\Microsoft.NET\Framework\v3.0\ . Darunter befinden sich für die WPF, WCF und WF jeweils ein Unterordner mit den Installationsdateien WF_3.0_x86.msi , wpf.msi und wcf.msi . Werden diese ausgeführt, kann evt. die Installation repariert oder entfernt werden. Im Falle der WCF kann auch der Aufruf von ServiceModelReg.exe -ua zur korrekten Deinstallation beitragen. Wenn das nicht hilft, gibt es ja noch Google oder es steht wieder einmal eine Neuinstallation von Windows an.
Textdarstellung mit der WPF
Obwohl die WPF mit ihren grafischen Fähigkeiten schon allerhand Ausdrucksmöglichkeiten besitzt, dürfen „einfache“ Textfeatures natürlich nicht fehlen. Um heutzutage in einer GUI einen formatierten Text auszugeben, sind bereits einige Klimmzüge notwendig. Insbesondere, wenn dieser Text verschiedene Formatierungen enthalten und vielleicht auch noch als Beschriftung in einer Komponente dienen soll. Mindestens letzteres ist ohne die Entwicklung eigener Komponenten bisher kaum möglich. Nun wurde bereits festgestellt, dass sich die Darstellung einer Komponente in der WPF aus verschiedenen Elementen zusammensetzt und dass man diese Zusammensetzung, den Visual Tree, auch selbst definieren kann. So weit zu gehen ist aber gar nicht notwendig, kann eine grafische Komponente doch grundsätzlich beliebige andere Komponenten enthalten, so auch Textelemente. Das folgende Beispiel setzt dies in die Praxis um: Statt die Beschriftung einer Schaltfläche direkt im Button -Element anzugeben, kann darin ein TextBlock -Element verschachtelt werden. Innerhalb eines Textblocks sind nun wieder verschiedene Angaben möglich. Einfachste Formatierungen wie kursiv, fett oder unterstrichen werden durch die Elemente I talic , B old und U nderline erreicht. Dazu ist einfach nur der betreffende Abschnitt in diese Elemente einzuschließen. Das TextBlock -Element kann auch einzeln angegeben werden. In diesem Fall wird es wie statischer Text behandelt. Das Ergebnis aus Listing 1 wird in Abbildung 2 gezeigt.
  1. Listing 1
  2. <StackPanel>
  3. <Button>
  4. <TextBlock>
  5. <Italic>
  6. Eine spezielle <Bold>Beschriftung</Bold>
  7. </Italic>
  8. </TextBlock>
  9. </Button>
  10. <TextBlock>
  11. Eine noch <Italic>speziellere </Italic>
  12. <Bold>Beschriftung</Bold>
  13. </TextBlock>
  14. </StackPanel>
Wird zum Erstellen der XAML-Seite der neue XAML-Designer aus der Preview von „Visual Studio Orcas“ verwendet, schleichen sich noch einige Darstellungsfehler (Punkt 1 und 2 in Abbildung 3) ein. Leerzeichen zwischen Formaten werden einfach nicht angezeigt. Im Zweifelsfall genügt es einfach die Anwendung auszuführen oder wenn möglich XAMLPad als Editor zu verwenden.
Das alles erinnert schon sehr an HTML und die Übereinstimmungen hören hier noch nicht auf. Mit dem Span -Element lassen sich bestimmte Textabschnitt speziell formatieren. So lässt sich z.B. die Schriftgröße des ersten Buchstaben eines Wortes vergrößern: <Span FontSi ze="15">G </Span> oWinFX . Zeilenumbrüche können über LineBreak -Elemente erzeugt werden. Ein weiteres Inline-Element ist der Hyperlink, über das die Darstellung eines Textabschnitts als Hyperlink erreicht wird. Die Funktionalität beim Anklicken des Links kann dann im Click -Ereignis untergebracht werden (Listing 2).
  1. Listing 2
  2. <Hyperlink NavigateUri="http://www.gowinfx.de" Click="OnHLClick">
  3. Alles zu WinFX
  4. </Hyperlink>
Das Textblock -Element sollte aber aus Performancegründen nur für kurze, ein- oder mehrzeilige Textabschnitte genutzt werden. Für größere Textpassagen oder gar einen Editor werden spezielle Komponenten bereitgestellt.
Darstellungseigenschaften
Bisher wurde der angezeigte Text nur durch die Verwendung verschiedener Elemente „formatiert“. Diese Elemente besitzen aber auch eine Menge von Eigenschaften, die in XAML über Attribute verändert werden können. Über die Inline-Elemente wie Span oder Italic lässt sich z.B. die eingeschlossene Schriftart des Texts formatieren. Die Attributnamen erinnern hier sehr an CSS (Cascading StyleSheets). Mittels der Eigenschaft FontFamily wird die Schriftart, mittels FontSize deren Größe und über FontWeight die Schriftstärke beeinflusst. Die Schriftfarbe wird einfach über die Eigenschaft Foreground gesetzt. Textblöcke verfügen über weitere Einstellmöglichkeiten. Diese wirken sich dann nicht nur auf einen Textabschnitt wie bei den Inline-Elementen sondern für den gesamten Inhalt eines Blocks aus. Mittels eines TextWrappings wird beispielsweise der automatische Zeilenumbruch aktiviert. Ansonsten fliest der Text einfach über den Rand hinaus, wenn er zu lang ist. Die Ausrichtung des gesamten Blocks wird über die Eigenschaft TextAlignment bestimmt, welche die Werte Left , Right , Center und Justify annehmen kann. Die Unterstützung des Blocksatzes ist dabei sicher die interessante Variante, denn dies erfordert von den Komponenten bereits eine umfangreichere Logik für die Darstellung und war deshalb in den aktuellen Komponenten häufig nicht verfügbar. Im Beispiel in Listing 3 wird ein TextBlock definiert. Dieser wird bereits mit einigen Eigenschaften vorbelegt - wie z.B. einer Zeilenhöhe von 20, einer Blockausrichtung und einem automatischen Zeilenumbruch. Damit der Text nicht so nah an den Rand des Containers reicht, wurde noch ein Rand über die Eigenschaft Margin festgelegt. Im Italic -Element wird das erste „Wort“ des Textes eingeschlossen, sodass es kursiv dargestellt wird. Außerdem werden Schriftstil und -farbe verändert. Das Element LineBreak , das sich mitten im Text befindet, erzeugt einen Zeilenumbruch. Wenn man nun die Größe des Fensters variiert, kann man insbesondere den Einfluss des Blocksatzes beobachten (Abbildung 4).
  1. Listing 3
  2. <TextBlock Margin="10" LineHeight="20" TextAlignment="Justify" TextWrapping="Wrap">
  3. <Italic FontFamily="Verdana" FontSize="13" FontWeight="SemiBold"
  4. Foreground="Blue">qwepoqwe</Italic> qwepoqwe pqowe qpweoqwe poqwieqwpoei
  5. qweqwpoei qweqiweu ie qwe ioqwue qwopeiu <Bold>qweoiu qweopiq uweqwe</Bold>
  6. piwque qwopieu<LineBreak/>qwopieu qweo iuqwe qw qwe ioqwue wqopieu qwopeiu
  7. wqeoiqwu ewqoieu oipquwe qwoeiu qwoeiu qwoeiu wqeqw
  8. </TextBlock>
Noch ein Wort zur Verwendung von Leerzeichen. Diese werden in einem XML-Dokument normalerweise auf ein einziges Leerzeichen zusammengedampft. Wenn mehrere Leerzeichen hintereinander folgen, wird daher nur eines angezeigt. Um diesem Automatismus zu entgehen, kann ein weiteres Attribut xml:space im TextBlock -Element angegeben werden. Um die Leerzeichen zu erhalten, muss dessen Wert auf preserve gesetzt werden, z.B. <TextBlock xml:space=" preserve "> . Jetzt bleiben Leerzeichen zwischen den Wörtern und auch am Zeilenanfang erhalten.
Komplexere Textausgabe
Ein TextBlock -Element ist nicht für umfangreichere Textausgaben vorgesehen und besitzt auch nicht alle möglichen Formatierungsmöglichkeiten der WPF. Das FlowDocument -Element kann neben den Inline-Elementen auch Block-Elemente zur Formatierung nutzen. Damit ergeben sich viele neue Anwendungsmöglichkeiten. Die einfachste Erweiterung ist der Einsatz von Absätzen, die durch ein Paragraph -Element festgelegt werden. Weiterhin ist es in einigen Elementen notwendig, deren Inhalt in einem Block-Element einzuschließen, und da bietet sich wieder das Paragraph -Element an. Das erste Einsatzgebiet wäre dann auch schon bei der Definition eines Listenelements. Mittels des Elements List wird eine Liste begonnen, der Einträge über ListItem -Elemente hinzugefügt werden. Über das Attribut MarkerStyle im List -Element lässt sich das Aufzählungszeichen festlegen, z.B. eine fortlaufende Nummerierung durch eine Zahl oder einen Buchstaben oder die Anzeige eines Kreises oder Rechtecks. Mittels dem Attribut StartIndex kann auch ein anderer Startindex zur Nummerierung festgelegt werden, in Listing 4 z.B. die Zahl 3. Abbildung 5 zeigt vier mögliche Aufzählungsvarianten.
  1. Listing 4
  2. <List MarkerStyle="Decimal" StartIndex="3">
  3. <ListItem>
  4. <Paragraph>Decimal 3</Paragraph>
  5. </ListItem>
  6. <ListItem>
  7. <Paragraph>Decimal 4</Paragraph>
  8. </ListItem>
  9. </List>
Ein weiteres typisches Element einer Textverarbeitung ist die Tabelle. Tabellen können über das Table -Element definiert werden und bestehen aus mehrere Spalten und Zeilen. Ähnlich einem Grid werden zu Beginn die benötigten Spalten festgelegt. Dann können über TableRowGroup -, TableRow - und TableCell -Elemente die Zeilen und Zellen erstellt und gefüllt werden. In Listing 5 wird eine Tabelle mit einer Überschrift in der ersten Zeile erstellt. Dazu werden zwei Zellen über das Attribut ColumnSpan miteinander verbunden. In einer weiteren Zeile werden dann die Inhalte zweier Zellen mit einem Text gefüllt. Das spektakuläre Ergebnis sieht man in Abbildung 6.
  1. Listing 5
  2. <Table CellSpacing="5">
  3. <Table.Columns>
  4. <TableColumn/>
  5. <TableColumn/>
  6. </Table.Columns>
  7. <TableRowGroup>
  8. <TableRow Background="LightBlue">
  9. <TableCell ColumnSpan="2">
  10. <Paragraph>Überschrift</Paragraph>
  11. </TableCell>
  12. </TableRow>
  13. <TableRow Background="LightYellow">
  14. <TableCell>
  15. <Paragraph>Zelle 1</Paragraph>
  16. </TableCell>
  17. <TableCell>
  18. <Paragraph>Zelle 2</Paragraph>
  19. </TableCell>
  20. </TableRow>
  21. </TableRowGroup>
  22. </Table>
Der Rahmen für die Textausgabe
Damit Tabellen, Listen und Absätze genutzt werden können, müssen diese in ein FlowDocument eingebettet werden. Für die Anzeige eines FlowDocuments ist ein weiteres Rahmenelement notwendig, welches das Dokument einbettet und die Navigation darin erlaubt. Für Flow-Dokumente stehen drei Anzeigekomponenten bereit. Der FlowDocumentReader ist die komplexeste davon, aber hauptsächlich auf die angebotene Funktionalität bezogen. Das FlowDocument wird in den FlowDocumentReader eingebettet, wie es Listing 6 zeigt.
  1. Listing 6
  2. <FlowDocumentReader>
  3. <FlowDocument>
  4. <!-- Block-Elemente -->
  5. <FlowDocument>
  6. <FlowDocumentReader>
Der Reader wird mit seinen Bestandteilen in Abbildung 7 gezeigt. In Punkt 1 wird das Dokument angezeigt. Durch den Klick auf die linke Lupe wird ein Eingabebereich geöffnet (Punkt 2) in dem nach Textstellen im Text gesucht werden kann. Die Seitenzahl (Punkt 3) ergibt sich je nach Größe des Dokumentfensters. Über die Pfeile lässt sich in den Seiten blättern. Über die Buttons (Punkt 4) kann die Ansicht auf 1 oder 2 Seiten oder fortlaufend eingestellt werden. Unter Punkt 5 kann dann noch der verwendete Zoom eingestellt werden. Im Dokument stehen über das Kontextmenü noch Funktionen zum Selektieren des gesamten Inhalts und Kopieren der aktuellen Markierung in die Zwischenablage bereit. Die beiden anderen Komponenten FlowDocumentPageViewer und FlowDocumentScrollViewer besitzen jeweils etwas weniger Funktionalität.
Floater und Figures
Innerhalb des Fließtextes lassen sich weitere, frei schwebende Blöcke, über Floater - und Figure -Elemente am Rand oder an einer fixen Position positionieren. Ein typisches Beispiel wäre eine Anzeige in einer Zeitung oder auf einer Webseite, die sich mitten im Text befindet. Über Figure -Elemente könnten aber auch Randnotizen implementiert werden. Die wichtigsten Eigenschaften zur Konfiguration eines Floaters sind seine Breite (die Höhe wird automatisch anhand der Seitenbreite und seines Inhalts berechnet) und seine horizontale Ausrichtung. In Listing 7 wird ein Floater am rechten Rand mit einer Breite von 100 angezeigt. Gegenüber einem Floater - kann ein Figure -Element genauer positioniert werden und mehr als eine Spalte in einem mehrspaltigen Dokument einnehmen. Zur Positionierung können z.B. die Eigenschaften HorizontalOffset und VerticalOffset sowie HorizontalAnchor verwendet werden. Zur Verwendung müssen die Elemente in einem anderen Block-Element eingebettet werden und können selbst wiederum verschiedene Blockelemente enthalten. In Abbildung 8 sind jeweils ein Figure (Punkt 1) und ein Floater (Punkt 2) enthalten, die durch den Code aus Listing 7 erzeugt werden.
  1. Listing 7
  2. <Paragraph>
  3. ....
  4. <Figure Width="120" Background="LightBlue"
  5. HorizontalAnchor="ContentCenter"
  6. HorizontalOffset="10" VerticalOffset="10">
  7. <Paragraph FontFamily="Verdane" FontSize="9">
  8. Schauen Sie mal unter http://www.gowinfx.de vorbei.
  9. </Paragraph>
  10. </Figure>
  11. </Paragraph>
  12. <Paragraph>
  13. ...
  14. <Floater FontFamily="Verdane" FontSize="9" Background="LightGreen"
  15. Width="100" HorizontalAlignment="Right">
  16. <Paragraph>
  17. Bemerkung: Dieser Text sollte noch einmal Korrektur gelesen werden.
  18. </Paragraph>
  19. </Floater>
  20. ...
  21. </Paragraph>
Neben den einfachen Textblöcken und Flow-Dokumenten bietet die WPF auch Fixed-Dokumente, die immer das gleiche Layout beibehalten. Diese Dokumente besitzen auf dem Bildschirm und auf dem Drucker die gleiche Darstellung. Die DocumentViewer -Komponente ist der Einstiegspunkt in die Arbeit mit diesem Dokumentformat. Neben vielen Features wie z.B. einem automatischen Zoom kann dieses Format aber nur gelesen und nicht editiert werden. Außerdem lassen sich diese Elemente nicht einfach über XAML erzeugen. Der AnnotationService erlaubt das Einfügen von Notizen und Markierungen in Textdokumente. Die Implementierung in eigenen Anwendungen benötigt die Unterstützung von C#- oder Visual-Basic-Code und steht in Flow- wie auch Fixed-Dokumenten zur Verfügung.
Fazit
Auch bei der Textausgabe lässt sich die WPF nicht lumpen. Zwar ist für die manuelle Erstellung von Textdokumenten viel Arbeit notwendig, aber dies wird in der Regel ja automatisiert erledigt. Durch das XML-Format (konkret XAML) und die starke Anlehnung an HTML ist eine Verarbeitung von vorhandenen Dokumenten relativ einfach, zumal es auch eine Programmierschnittstelle gibt, um direkt mit Methoden auf die einzelnen Inhalte eines Dokuments zuzugreifen. Der Programmierer wird damit auch bei der Textdarstellung immer mehr zum „Designer“ einer Anwendung bzw. muss in der WPF deutlich mehr Wert auf die Designmöglichkeiten von Textdarstellungen legen als bisher. Die Namensänderung von WinFX in .NET Framework 3.0 hat der Begeisterung von Dirk Frischalowski, der bereits seit 2004 ein großer Fan der Betriebssystemerweiterung war, keinen Abbruch getan. Seine WPF-Serie wird daher auch in Zukunft Entwickler mit aktuellen Informationen rund um das .NET Framework 3.0 versorgen. Seine WinFX-Homepage hat nach wie vor die Adresse www.gowinfx.de.
Links & Literatur


Anzeige

Kommentare

zurück zum Seitenanfang