Cenni preliminari sui documenti dinamici
Aggiornamento: novembre 2007
I documenti dinamici sono stati progettati per ottimizzare la visualizzazione e la leggibilità. Anziché essere impostati su un layout predefinito, questi documenti consentono di regolare e di far scorrere il contenuto in modo dinamico in base alle variabili in fase di esecuzione, ad esempio, le dimensioni della finestra, la risoluzione del dispositivo e le preferenze facoltative dell'utente. Questi documenti offrono inoltre funzionalità avanzate del documento, quali paginazione e colonne. In questo argomento vengono forniti i cenni preliminari sui documenti dinamici e su come crearli.
Nel presente argomento sono contenute le seguenti sezioni.
- Definizione di documento dinamico
- Tipi di documenti dinamici
- Creazione di contenuto del flusso
- Classi correlate al flusso
- Schema del contenuto
- Personalizzazione del testo
- Argomenti correlati
Definizione di documento dinamico
I documenti dinamici sono stati progettati per "adattare il flusso del contenuto" in base alle dimensioni della finestra, alla risoluzione del dispositivo e ad altre variabili di ambiente. Tali documenti dispongono inoltre di numerose funzionalità incorporate tra cui la ricerca, le modalità di visualizzazione che ottimizzano la leggibilità e la possibilità di modificare le dimensioni e l'aspetto dei tipi di carattere. I documenti dinamici sono meglio utilizzati quando la semplicità di lettura rappresenta lo scenario principale di utilizzo del documento. I documenti statici, al contrario, sono stati progettati per avere una presentazione statica; risultano utili quando la fedeltà del contenuto di origine è fondamentale. Per ulteriori informazioni sui diversi tipi di documenti, vedere Documenti di Windows Presentation Foundation.
Nell'illustrazione riportata di seguito viene mostrato un documento dinamico di esempio visualizzato in molte finestre di dimensioni diverse. Quando l'area di visualizzazione viene modificata, il contenuto adatta il flusso per un migliore utilizzo dello spazio disponibile.
Come mostrato nell'immagine precedente, il contenuto del flusso può contenere numerosi componenti, compresi i paragrafi, gli elenchi, le immagini, le tabelle e altro ancora. Questi componenti corrispondono agli elementi nel markup e agli oggetti nel codice procedurale. Queste classi verranno esaminate dettagliatamente più avanti nella sezione Classi correlate al flusso di questi cenni preliminari. Di seguito è riportato un semplice esempio di codice che crea un documento dinamico costituito da un paragrafo con del testo in grassetto e da un elenco.
<!-- This simple flow document includes a paragraph with some
bold text in it and a list. -->
<FlowDocumentReader xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml">
<FlowDocument>
<Paragraph>
<Bold>Some bold text in the paragraph.</Bold>
Some text that is not bold.
</Paragraph>
<List>
<ListItem>
<Paragraph>ListItem 1</Paragraph>
</ListItem>
<ListItem>
<Paragraph>ListItem 2</Paragraph>
</ListItem>
<ListItem>
<Paragraph>ListItem 3</Paragraph>
</ListItem>
</List>
</FlowDocument>
</FlowDocumentReader>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
namespace SDKSample
{
public partial class SimpleFlowExample : Page
{
public SimpleFlowExample()
{
Paragraph myParagraph = new Paragraph();
// Add some Bold text to the paragraph
myParagraph.Inlines.Add(new Bold(new Run("Some bold text in the paragraph.")));
// Add some plain text to the paragraph
myParagraph.Inlines.Add(new Run(" Some text that is not bold."));
// Create a List and populate with three list items.
List myList = new List();
// First create paragraphs to go into the list item.
Paragraph paragraphListItem1 = new Paragraph(new Run("ListItem 1"));
Paragraph paragraphListItem2 = new Paragraph(new Run("ListItem 2"));
Paragraph paragraphListItem3 = new Paragraph(new Run("ListItem 3"));
// Add ListItems with paragraphs in them.
myList.ListItems.Add(new ListItem(paragraphListItem1));
myList.ListItems.Add(new ListItem(paragraphListItem2));
myList.ListItems.Add(new ListItem(paragraphListItem3));
// Create a FlowDocument with the paragraph and list.
FlowDocument myFlowDocument = new FlowDocument();
myFlowDocument.Blocks.Add(myParagraph);
myFlowDocument.Blocks.Add(myList);
// Add the FlowDocument to a FlowDocumentReader Control
FlowDocumentReader myFlowDocumentReader = new FlowDocumentReader();
myFlowDocumentReader.Document = myFlowDocument;
this.Content = myFlowDocumentReader;
}
}
}
Il frammento di codice sarà del tipo riportato nell'illustrazione indicata di seguito.
In questo esempio viene utilizzato il controllo FlowDocumentReader per ospitare il contenuto del flusso. Per ulteriori informazioni sui controlli che ospitano il contenuto del flusso vedere Tipi di documenti dinamici. Gli elementi Paragraph, List, ListItem e Bold sono utilizzati per controllare la formattazione del contenuto in base all'ordine nel markup. L'elemento Bold, ad esempio, si estende solo su parte del testo nel paragrafo; di conseguenza, solo parte del testo è in grassetto. Se già utilizzato in precedenza, HTML risulterà familiare.
Come evidenziato nell'illustrazione sopra indicata, esistono numerose funzionalità incorporate nei documenti dinamici:
Cerca: consente all'utente di eseguire ricerche full-text di un intero documento.
Modalità di visualizzazione: consente all'utente di selezionare la modalità di visualizzazione preferita, inclusa una modalità di visualizzazione a pagina singola (una pagina per volta), una modalità di visualizzazione a pagina doppia (formato lettura libro) e una modalità di visualizzazione a spostamento continuo (infinito). Per ulteriori informazioni sulle modalità di visualizzazione, vedere FlowDocumentReaderViewingMode.
Controlli spostamento tra le pagine: se la modalità di visualizzazione del documento utilizza le pagine, i controlli di spostamento tra le pagine includono un pulsante per passare alla pagina successiva (freccia verso il basso) o alla pagina precedente ( freccia verso l'alto), così come indicatori del numero della pagina corrente e del numero totale di pagine. Inoltre è possibile scorrere le pagine utilizzando i tasti di direzione della tastiera.
Zoom: i controlli dello zoom consentono all'utente di aumentare o diminuire il livello dello zoom facendo clic sui pulsanti più o meno, rispettivamente. I controlli dello zoom includono anche un dispositivo di scorrimento per regolare il livello dello zoom. Per ulteriori informazioni, vedere Zoom.
Queste funzionalità possono essere modificate in base al controllo utilizzato per ospitare il contenuto del flusso. I diversi controlli vengono descritti nella sezione seguente.
Tipi di documenti dinamici
La visualizzazione del contenuto del documento dinamico e la modalità di visualizzazione corrispondente dipendono dall'oggetto utilizzato per ospitare il contenuto del flusso. Sono quattro i controlli che supportano la visualizzazione del contenuto del flusso: FlowDocumentReader, FlowDocumentPageViewer, RichTextBox e FlowDocumentScrollViewer. Questi controlli vengono descritti brevemente di seguito.
Nota: l'oggetto FlowDocument è necessario per ospitare direttamente il contenuto del flusso in modo che tutti i controlli di visualizzazione utilizzino FlowDocument per consentire l'hosting del contenuto del flusso.
Controllo FlowDocumentReader
FlowDocumentReader include funzionalità che consentono all'utente di scegliere dinamicamente tra le varie modalità di visualizzazione, inclusa una modalità di visualizzazione a pagina singola (una pagina per volta), una modalità di visualizzazione a pagina doppia (formato lettura libro) e una modalità di visualizzazione a spostamento continuo (infinito). Per ulteriori informazioni su queste modalità di visualizzazione, vedere FlowDocumentReaderViewingMode. Se la possibilità di passare dinamicamente da una modalità di visualizzazione all'altra non è necessaria, i controlli FlowDocumentPageViewer e FlowDocumentScrollViewer forniscono visualizzatori di contenuto del flusso più semplici che sono fissi a una modalità di visualizzazione particolare.
Controlli FlowDocumentPageViewer e FlowDocumentScrollViewer
Il controllo FlowDocumentPageViewer visualizza il contenuto nella modalità di visualizzazione di una pagina alla volta mentre il controllo FlowDocumentScrollViewer visualizza il contenuto nella modalità di scorrimento continuo. FlowDocumentPageViewer e FlowDocumentScrollViewer rimangono fissi in una particolare modalità di visualizzazione. Effettuare il confronto con il controllo FlowDocumentReader, che include funzionalità che consentono all'utente di scegliere in modo dinamico tra le varie modalità di visualizzazione (fornite dall'enumerazione FlowDocumentReaderViewingMode), a discapito di un utilizzo di risorse maggiore rispetto a FlowDocumentPageViewer o FlowDocumentScrollViewer.
Per impostazione predefinita, viene sempre visualizzata una barra di scorrimento verticale e diventa visibile una barra di scorrimento orizzontale, se necessario. La UI predefinita dell'oggetto FlowDocumentScrollViewer non include una barra degli strumenti; tuttavia, la proprietà IsToolBarVisible può essere utilizzata per attivare la barra degli strumenti incorporata.
RichTextBox
Utilizzare un oggetto RichTextBox quando si desidera consentire all'utente di modificare il contenuto del flusso. Se si desidera creare, ad esempio, un editor che consenta all'utente di modificare elementi come tabelle, formattazione di corsivo e grassetto e così via, utilizzare il controllo RichTextBox. Per ulteriori informazioni, vedere Cenni generali sul controllo RichTextBox.
Nota: il comportamento del contenuto del flusso all'interno di RichTextBox è leggermente diverso rispetto al comportamento del contenuto del flusso incluso in altri controlli. Ad esempio, in un oggetto RichTextBox non sono presenti colonne, pertanto non è previsto un comportamento di ridimensionamento automatico. Inoltre, le funzionalità incorporate solite del contenuto del flusso quali la ricerca, la modalità di visualizzazione, lo spostamento sulle pagine e lo zoom non sono disponibili in un oggetto RichTextBox.
Creazione di contenuto del flusso
Il contenuto del flusso può essere complesso, composto da vari elementi tra cui testo, immagini, tabelle e anche classi derivate UIElement come i controlli. Per comprendere la modalità di creazione di un contenuto del flusso complesso, i punti riportati di seguito sono fondamentali.
Classi correlate al flusso: ogni classe utilizzata nel contenuto del flusso ha uno scopo specifico. Inoltre, la relazione gerarchica tra le classi di flusso facilita la comprensione della modalità di utilizzo. Ad esempio, le classi derivate dalla classe Block vengono utilizzate per contenere altri oggetti mentre le classi derivate da Inline contengono gli oggetti visualizzati.
Schema del contenuto: un documento dinamico può richiedere un numero considerevole di elementi nidificati. Nello schema del contenuto vengono specificate le possibili relazioni padre/figlio tra elementi.
Ognuna di queste aree verrà esaminata in maniera dettagliata nella sezioni seguenti.
Classi correlate al flusso
Nel diagramma riportato di seguito sono illustrati gli oggetti utilizzati più di frequente con il contenuto del flusso:
Ai fini del contenuto del flusso, esistono due categorie importanti:
Classi derivate da Block: definite anche "Elementi del contenuto di Block" o semplicemente "Elementi Block". Gli elementi che ereditano dalla classe Block possono essere utilizzati per raggruppare elementi in un'entità principale comune oppure applicare attributi comuni a un gruppo.
Classi derivate da Inline: definite anche "Elementi del contenuto di Inline" o semplicemente "Elementi Inline". Gli elementi che ereditano da Inline o sono contenuti in un elemento Block o in un altro elemento Inline. Gli elementi Inline sono spesso utilizzati come contenitori diretti del contenuto che è sottoposto al rendering dello schermo. Ad esempio, un oggetto Paragraph (elemento Block) può contenere un oggetto Run (elemento Inline) ma la classe Run contiene in realtà il testo che è sottoposto al rendering dello schermo.
Ciascuna classe di queste due categorie è descritta brevemente di seguito.
Classi derivate da Block
Paragraph
Paragraph è utilizzato solitamente per raggruppare il contenuto in un paragrafo. L'utilizzo più semplice e più comune di Paragraph è creare un paragrafo di testo.
<FlowDocument xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml">
<Paragraph>
Some paragraph text.
</Paragraph>
</FlowDocument>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
namespace SDKSample
{
public partial class ParagraphExample : Page
{
public ParagraphExample()
{
// Create paragraph with some text.
Paragraph myParagraph = new Paragraph();
myParagraph.Inlines.Add(new Run("Some paragraph text."));
// Create a FlowDocument and add the paragraph to it.
FlowDocument myFlowDocument = new FlowDocument();
myFlowDocument.Blocks.Add(myParagraph);
this.Content = myFlowDocument;
}
}
}
È tuttavia possibile contenere anche altri elementi derivati da Inline come illustrato di seguito.
Sezione
Section è utilizzata per contenere solo altri elementi derivati da Block. Non applica alcuna formattazione predefinita agli elementi in esso contenuti. Tuttavia, tutti i valori di proprietà impostati su un oggetto Section vengono applicati ai relativi elementi figlio. Una sezione consente inoltre di effettuare iterazioni a livello di codice mediante il relativo insieme figlio. Section è utilizzata in modo analogo al tag <DIV> in HTML.
Nell'esempio riportato di seguito, tre paragrafi sono definiti in Section. La sezione ha un valore della proprietà Background equivalente a rosso, pertanto anche il colore dello sfondo dei paragrafi è rosso.
<FlowDocument xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml">
<!-- By default, Section applies no formatting to elements contained
within it. However, in this example, the section has a Background
property value of "Red", therefore, the three paragraphs (the block)
inside the section also have a red background. -->
<Section Background="Red">
<Paragraph>
Paragraph 1
</Paragraph>
<Paragraph>
Paragraph 2
</Paragraph>
<Paragraph>
Paragraph 3
</Paragraph>
</Section>
</FlowDocument>
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Documents;
namespace SDKSample
{
public partial class SectionExample : Page
{
public SectionExample()
{
// Create three paragraphs
Paragraph myParagraph1 = new Paragraph(new Run("Paragraph 1"));
Paragraph myParagraph2 = new Paragraph(new Run("Paragraph 2"));
Paragraph myParagraph3 = new Paragraph(new Run("Paragraph 3"));
// Create a Section and add the three paragraphs to it.
Section mySection = new Section();
mySection.Background = Brushes.Red;
mySection.Blocks.Add(myParagraph1);
mySection.Blocks.Add(myParagraph2);
mySection.Blocks.Add(myParagraph3);
// Create a FlowDocument and add the section to it.
FlowDocument myFlowDocument = new FlowDocument();
myFlowDocument.Blocks.Add(mySection);
this.Content = myFlowDocument;
}
}
}
BlockUIContainer
BlockUIContainer consente di incorporare gli elementi UIElement (ad esempio Button) nel contenuto del flusso derivato da Block. InlineUIContainer (vedere di seguito) è utilizzata per incorporare gli elementi UIElement nel contenuto del flusso derivato da Inline. BlockUIContainer e InlineUIContainer sono importanti in quanto non esiste un altro modo per utilizzare un oggetto UIElement nel contenuto del flusso a meno che non sia contenuto in uno di questi due elementi.
Nell'esempio riportato di seguito viene illustrato come utilizzare l'elemento BlockUIContainer per ospitare gli oggetti UIElement nel contenuto del flusso.
<FlowDocument ColumnWidth="400">
<Section Background="GhostWhite">
<Paragraph>
A UIElement element may be embedded directly in flow content
by enclosing it in a BlockUIContainer element.
</Paragraph>
<BlockUIContainer>
<Button>Click me!</Button>
</BlockUIContainer>
<Paragraph>
The BlockUIContainer element may host no more than one top-level
UIElement. However, other UIElements may be nested within the
UIElement contained by an BlockUIContainer element. For example,
a StackPanel can be used to host multiple UIElement elements within
a BlockUIContainer element.
</Paragraph>
<BlockUIContainer>
<StackPanel>
<Label Foreground="Blue">Choose a value:</Label>
<ComboBox>
<ComboBoxItem IsSelected="True">a</ComboBoxItem>
<ComboBoxItem>b</ComboBoxItem>
<ComboBoxItem>c</ComboBoxItem>
</ComboBox>
<Label Foreground ="Red">Choose a value:</Label>
<StackPanel>
<RadioButton>x</RadioButton>
<RadioButton>y</RadioButton>
<RadioButton>z</RadioButton>
</StackPanel>
<Label>Enter a value:</Label>
<TextBox>
A text editor embedded in flow content.
</TextBox>
</StackPanel>
</BlockUIContainer>
</Section>
</FlowDocument>
Nella figura riportata di seguito viene illustrato il rendering di questo esempio.
Elenco
List è utilizzato per creare un elenco puntato o numerico. Impostare la proprietà MarkerStyle su un valore di enumerazione TextMarkerStyle per determinare lo stile dell'elenco. Nell'esempio riportato di seguito viene illustrato come creare un elenco semplice.
<FlowDocument xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml">
<List>
<ListItem>
<Paragraph>
List Item 1
</Paragraph>
</ListItem>
<ListItem>
<Paragraph>
List Item 2
</Paragraph>
</ListItem>
<ListItem>
<Paragraph>
List Item 3
</Paragraph>
</ListItem>
</List>
</FlowDocument>
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Documents;
namespace SDKSample
{
public partial class ListExample : Page
{
public ListExample()
{
// Create three paragraphs
Paragraph myParagraph1 = new Paragraph(new Run("List Item 1"));
Paragraph myParagraph2 = new Paragraph(new Run("List Item 2"));
Paragraph myParagraph3 = new Paragraph(new Run("List Item 3"));
// Create the ListItem elements for the List and add the
// paragraphs to them.
ListItem myListItem1 = new ListItem();
myListItem1.Blocks.Add(myParagraph1);
ListItem myListItem2 = new ListItem();
myListItem2.Blocks.Add(myParagraph2);
ListItem myListItem3 = new ListItem();
myListItem3.Blocks.Add(myParagraph3);
// Create a List and add the three ListItems to it.
List myList = new List();
myList.ListItems.Add(myListItem1);
myList.ListItems.Add(myListItem2);
myList.ListItems.Add(myListItem3);
// Create a FlowDocument and add the section to it.
FlowDocument myFlowDocument = new FlowDocument();
myFlowDocument.Blocks.Add(myList);
this.Content = myFlowDocument;
}
}
}
Nota: List è l'unico elemento del flusso che utilizza l'elemento ListItemCollection per gestire gli elementi figlio.
Tabella
L'oggetto Table è utilizzato per creare una tabella. Table è simile all'elemento Grid ma possiede più funzionalità e pertanto richiede un sovraccarico di risorse maggiore. Poiché Grid è un oggetto UIElement, non può essere utilizzato nel contenuto del flusso a meno che non sia contenuto in una classe BlockUIContainer o InlineUIContainer. Per ulteriori informazioni su Table, vedere Cenni preliminari sull'elemento Table.
Classi derivate da Inline
Run
Run è utilizzata per contenere testo non formattato. Ci si aspetterebbe che gli oggetti Run venissero ampiamente utilizzati nel contenuto del flusso, tuttavia, nel markup, non è necessario utilizzare in modo esplicito gli elementi Run. Nel markup riportato di seguito, ad esempio, il primo Paragraph, contrariamente al secondo, specifica l'elemento Run in modo esplicito. Entrambi i paragrafi generano output identici.
<Paragraph>
<Run>Paragraph that explicitly uses the Run element.</Run>
</Paragraph>
<Paragraph>
This Paragraph omits the the Run element in markup. It renders
the same as a Paragraph with Run used explicitly.
</Paragraph>
Nota: la classe Run è necessaria quando si creano e modificano documenti dinamici mediante codice.
Span
Span raggruppa insieme altri elementi di contenuto di Inline. Nessun rendering inerente viene applicato al contenuto all'interno di un elemento Span. Tuttavia, gli elementi che ereditano dalla classe Span inclusi Hyperlink, Bold, Italic e Underline applicano la formattazione al testo.
Di seguito è riportato un esempio di utilizzo di Span per contenere il contenuto Inline comprendente del testo, un elemento Bold e un elemento Button.
<FlowDocument xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml">
<Paragraph>
Text before the Span. <Span Background="Red">Text within the Span is
red and <Bold>this text is inside the Span-derived element Bold.</Bold>
A Span can contain more then text, it can contain any inline content. For
example, it can contain a
<InlineUIContainer>
<Button>Button</Button>
</InlineUIContainer>
or other UIElement, a Floater, a Figure, etc.</Span>
</Paragraph>
</FlowDocument>
Nella schermata riportata di seguito viene illustrato il rendering di questo esempio.
InlineUIContainer
InlineUIContainer consente di incorporare gli elementi UIElement (ad esempio un controllo come Button) in un elemento di contenuto Inline. Questo elemento è l'equivalente in linea dell'oggetto BlockUIContainer descritto in precedenza. Nell'esempio riportato di seguito, l'elemento InlineUIContainer viene utilizzato per inserire un elemento in linea Button in un oggetto Paragraph.
<FlowDocument xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml">
<Paragraph>
Text to precede the button...
<!-- Set the BaselineAlignment property to "Bottom"
so that the Button aligns properly with the text. -->
<InlineUIContainer BaselineAlignment="Bottom">
<Button>Button</Button>
</InlineUIContainer>
Text to follow the button...
</Paragraph>
</FlowDocument>
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Documents;
namespace SDKSample
{
public partial class InlineUIContainerExample : Page
{
public InlineUIContainerExample()
{
Run run1 = new Run(" Text to precede the button... ");
Run run2 = new Run(" Text to follow the button... ");
// Create a new button to be hosted in the paragraph.
Button myButton = new Button();
myButton.Content = "Click me!";
// Create a new InlineUIContainer to contain the Button.
InlineUIContainer myInlineUIContainer = new InlineUIContainer();
// Set the BaselineAlignment property to "Bottom" so that the
// Button aligns properly with the text.
myInlineUIContainer.BaselineAlignment = BaselineAlignment.Bottom;
// Asign the button as the UI container's child.
myInlineUIContainer.Child = myButton;
// Create the paragraph and add content to it.
Paragraph myParagraph = new Paragraph();
myParagraph.Inlines.Add(run1);
myParagraph.Inlines.Add(myInlineUIContainer);
myParagraph.Inlines.Add(run2);
// Create a FlowDocument and add the paragraph to it.
FlowDocument myFlowDocument = new FlowDocument();
myFlowDocument.Blocks.Add(myParagraph);
this.Content = myFlowDocument;
}
}
}
Nota:InlineUIContainer non deve essere utilizzato in modo esplicito nel markup. Se viene omesso, verrà creato un elemento InlineUIContainer in ogni caso quando viene compilato il codice.
Figure e Floater
Figure e Floater sono utilizzati per incorporare del contenuto nei documenti dinamici con proprietà di posizionamento che possono essere personalizzate senza tenere conto del flusso di contenuto principale. Gli elementi Figure o Floater sono spesso utilizzati per evidenziare o sottolineare parti del contenuto, per ospitare immagini di supporto o altro contenuto all'interno del flusso di contenuto principale, oppure per inserire in modo approssimativo del contenuto correlato, ad esempio annunci.
Nell'esempio riportato di seguito viene illustrato come incorporare un elemento Figure in un paragrafo di testo.
<FlowDocument xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml">
<Paragraph>
<Figure
Width="300" Height="100"
Background="GhostWhite" HorizontalAnchor="PageLeft" >
<Paragraph FontStyle="Italic" Background="Beige" Foreground="DarkGreen" >
A Figure embeds content into flow content with placement properties
that can be customized independently from the primary content flow
</Paragraph>
</Figure>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy
nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi
enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis
nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure.
</Paragraph>
</FlowDocument>
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Documents;
namespace SDKSample
{
public partial class FigureExample : Page
{
public FigureExample()
{
// Create strings to use as content.
string strFigure = "A Figure embeds content into flow content with" +
" placement properties that can be customized" +
" independently from the primary content flow";
string strOther = "Lorem ipsum dolor sit amet, consectetuer adipiscing" +
" elit, sed diam nonummy nibh euismod tincidunt ut laoreet" +
" dolore magna aliquam erat volutpat. Ut wisi enim ad" +
" minim veniam, quis nostrud exerci tation ullamcorper" +
" suscipit lobortis nisl ut aliquip ex ea commodo consequat." +
" Duis autem vel eum iriure.";
// Create a Figure and assign content and layout properties to it.
Figure myFigure = new Figure();
myFigure.Width = new FigureLength(300);
myFigure.Height = new FigureLength(100);
myFigure.Background = Brushes.GhostWhite;
myFigure.HorizontalAnchor = FigureHorizontalAnchor.PageLeft;
Paragraph myFigureParagraph = new Paragraph(new Run(strFigure));
myFigureParagraph.FontStyle = FontStyles.Italic;
myFigureParagraph.Background = Brushes.Beige;
myFigureParagraph.Foreground = Brushes.DarkGreen;
myFigure.Blocks.Add(myFigureParagraph);
// Create the paragraph and add content to it.
Paragraph myParagraph = new Paragraph();
myParagraph.Inlines.Add(myFigure);
myParagraph.Inlines.Add(new Run(strOther));
// Create a FlowDocument and add the paragraph to it.
FlowDocument myFlowDocument = new FlowDocument();
myFlowDocument.Blocks.Add(myParagraph);
this.Content = myFlowDocument;
}
}
}
L'illustrazione seguente mostra come viene eseguito il rendering di questo esempio.
Figure e Floater sono per molti aspetti diversi e vengono utilizzati per scenari differenti.
Figure:
Può essere posizionata: è possibile impostarne gli ancoraggi orizzontali e verticali per ancorarla in relazione alla pagina, al contenuto, alla colonna o al paragrafo. È anche possibile utilizzare le proprietà HorizontalOffset e VerticalOffset per specificare offset arbitrari.
È ridimensionabile a più di una colonna: è possibile impostare l'altezza e la larghezza di Figure su multipli dell'altezza e della larghezza della pagina, del contenuto o della colonna. Nel caso della pagina e del contenuto, i multipli superiori a 1 non sono consentiti. Ad esempio, è possibile impostare la larghezza di un oggetto Figure come "0,5 pagina", "0,25 contenuto" o "2 colonna". È anche possibile impostare l'altezza e la larghezza su valori di pixel assoluti.
Non esegue alcuna impaginazione: se il contenuto di un oggetto Figure non rientra perfettamente nell'elemento Figure, questo eseguirà il rendering della parte di contenuto rientrante al suo interno e il resto del contenuto andrà perso.
Floater:
Non può essere posizionato ed esegue il rendering ovunque vi sia uno spazio a disposizione. Non è possibile ancorare né impostare l'offset di un oggetto Floater.
Non può essere ridimensionato a più di una colonna: per impostazione predefinita, Floater viene dimensionato a una colonna. Possiede una proprietà Width che può essere impostata su un valore di pixel assoluto, ma se questo valore è superiore alla larghezza di una colonna allora viene ignorato e il floater viene dimensionato a una colonna. È possibile ridimensionarlo a una larghezza inferiore a una colonna, impostando la larghezza corretta in pixel, ma il ridimensionamento non è relativo alla colonna, quindi "0,5 colonna" non è un'espressione valida per la larghezza di Floater. Floater non possiede alcuna proprietà di altezza, la quale non può essere impostata e dipende dal contenuto.
Floater esegue l'impaginazione: se il contenuto nella larghezza specificata si estende per un'altezza superiore a 1 colonna, il floater spezza il contenuto e lo impagina nella colonna o pagina successiva.
Figure è l'oggetto ideale nel quale inserire un contenuto autonomo di cui si desidera controllare le dimensioni e il posizionamento, essendo certi che tale contenuto rientrerà nelle dimensioni specificate. Floater è l'oggetto ideale nel quale inserire un contenuto più dinamico che scorre in modo analogo al contenuto della pagina principale, dal quale però resta separato.
LineBreak
LineBreak determina un'interruzione di riga nel contenuto del flusso. Nell'esempio seguente viene illustrato l'utilizzo di LineBreak.
<FlowDocument xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml">
<Paragraph>
Before the LineBreak in Paragraph.
<LineBreak />
After the LineBreak in Paragraph.
<LineBreak/><LineBreak/>
After two LineBreaks in Paragraph.
</Paragraph>
<Paragraph>
<LineBreak/>
</Paragraph>
<Paragraph>
After a Paragraph with only a LineBreak in it.
</Paragraph>
</FlowDocument>
Nella schermata riportata di seguito viene illustrato il rendering di questo esempio.
Elementi dell'insieme di flusso
In molti degli esempi precedenti, BlockCollection e InlineCollection sono utilizzati per costruire il contenuto del flusso a livello di codice. Ad esempio, per aggiungere un oggetto Paragraph, utilizzare la sintassi:
…
myParagraph.Inlines.Add(new Run("Some text"));
…
In questo modo Run viene aggiunto all'oggetto InlineCollection dell'elemento Paragraph. Si ottiene lo stesso risultato dell'oggetto Run implicito trovato all'interno di un elemento Paragraph nel markup:
…
<Paragraph>
Some Text
</Paragraph>
…
Come esempio di utilizzo di BlockCollection, nell'esempio riportato di seguito viene creato un nuovo oggetto Section e viene utilizzato il metodo Add per aggiungere un nuovo elemento Paragraph ai contenuti Section.
Section secx = new Section();
secx.Blocks.Add(new Paragraph(new Run("A bit of text content...")));
Oltre ad aggiungere elementi a un insieme di flusso, è anche possibile rimuoverli. Nell'esempio riportato di seguito viene eliminato l'ultimo elemento Inline di Span.
spanx.Inlines.Remove(spanx.Inlines.LastInline);
Nell'esempio riportato di seguito viene cancellato tutto il contenuto (gli elementi Inline) dall'oggetto Span.
spanx.Inlines.Clear();
Quando si utilizza il contenuto del flusso a livello di codice, l'utilizzo di questi insiemi sarà diffuso.
L'utilizzo di un oggetto InlineCollection (Inline) o BlockCollection (Block) per contenere gli elementi figlio da parte di un elemento di flusso dipende dal tipo di elementi figlio (Block o Inline) contenuto dal padre. Le regole di contenimento per gli elementi di contenuto di flusso sono riepilogate nello schema di contenuto nella sezione seguente.
Nota: esiste un terzo tipo di insieme utilizzato con il contenuto di flusso, ListItemCollection, ma questo insieme viene utilizzato solo con un oggetto List. Inoltre esistono numerosi insiemi utilizzati con Table. Per ulteriori informazioni, vedere Cenni preliminari sull'elemento Table.
Schema del contenuto
Dato il numero di elementi differenti di contenuto del flusso, può essere dominante per tenere traccia del tipo di elementi figli contenuto da un elemento. Nel diagramma riportato di seguito sono riepilogate le regole di contenimento per gli elementi di flusso. Le frecce rappresentano le possibili relazioni padre/figlio.
Come è possibile osservare dal diagramma precedente, gli elementi figlio consentiti per un elemento non vengono necessariamente determinati in base a un elemento Block o a un elemento Inline. Ad esempio, un oggetto Span (un elemento Inline) può possedere solo elementi figlio Inline mentre un oggetto Figure (anche un elemento Inline) può possedere solo elementi figlio Block. Pertanto, un diagramma è utile a determinare rapidamente quale elemento può essere contenuto in un altro elemento. Ad esempio, è possibile utilizzare il diagramma per determinare la modalità di costruzione del contenuto di flusso di un oggetto RichTextBox.
1. Un oggetto RichTextBox deve contenere un oggetto FlowDocument che a sua volta deve includere un oggetto derivato da Block. Di seguito viene riportato il corrispondente segmento del diagramma precedente.
Pertanto, l'aspetto del markup potrebbe essere quello visualizzato di seguito.
<RichTextBox>
<FlowDocument>
<!-- One or more Block-derived object… -->
</FlowDocument>
</RichTextBox>
2. In base al diagramma, è possibile scegliere tra diversi elementi Block, inclusi Paragraph, Section, Table, List e BlockUIContainer (vedere le classi derivate da Block sopra riportate). Si supponga ad esempio di cercare un oggetto Table. In base al diagramma precedente, un oggetto Table contiene un oggetto TableRowGroup che include a sua volta elementi TableRow, che contengono elementi TableCell che includono infine un oggetto derivato da Block. Di seguito viene riportato il segmento corrispondente relativo a Table, tratto dal diagramma precedente.
Di seguito il markup corrispondente.
<RichTextBox>
<FlowDocument>
<Table>
<TableRowGroup>
<TableRow>
<TableCell>
<!-- One or more Block-derived object… -->
</TableCell>
</TableRow>
</TableRowGroup>
</Table>
</FlowDocument>
</RichTextBox>
3. Anche in questo caso, uno o più elementi Block devono essere presenti in un oggetto TableCell. Per rendere più evidente l'esempio, viene inserito del testo nella cella. A tal fine, si utilizza un oggetto Paragraph con un elemento Run. Di seguito vengono riportati i segmenti corrispondenti del diagramma, che indicano che un oggetto Paragraph può accettare un elemento Inline e che un oggetto Run (un elemento Inline) può accettare solo il testo normale.
Di seguito viene mostrato l'intero esempio a livello di markup.
<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml">
<RichTextBox>
<FlowDocument>
<!-- Normally a table would have multiple rows and multiple
cells but this code is for demonstration purposes.-->
<Table>
<TableRowGroup>
<TableRow>
<TableCell>
<Paragraph>
<!-- The schema does not actually require
explicit use of the Run tag in markup. It
is only included here for clarity. -->
<Run>Paragraph in a Table Cell.</Run>
</Paragraph>
</TableCell>
</TableRow>
</TableRowGroup>
</Table>
</FlowDocument>
</RichTextBox>
</Page>
Personalizzazione del testo
In genere il testo è il tipo di contenuto più diffuso in un documento dinamico. Sebbene gli oggetti illustrati in precedenza possano essere utilizzati per controllare molti aspetti della modalità di esecuzione del rendering del testo, esistono alcuni altri metodi per la personalizzazione del testo descritti in questa sezione.
Decorazioni di testo
Le decorazioni di testo consentono di applicare gli effetti sottolineato, linea sopra, linea di base e barrato al testo (vedere le immagini riportate di seguito). Queste decorazioni vengono aggiunte mediante la proprietà TextDecorations esposta da un numero di oggetti comprendenti Inline, Paragraph, TextBlocke TextBox.
Nell'esempio riportato di seguito viene illustrato come impostare la proprietà TextDecorations di un oggetto Paragraph.
<FlowDocument ColumnWidth="200">
<Paragraph TextDecorations="Strikethrough">
This text will render with the strikethrough effect.
</Paragraph>
</FlowDocument>
Paragraph parx = new Paragraph(new Run("This text will render with the strikethrough effect."));
parx.TextDecorations = TextDecorations.Strikethrough;
Nella figura riportata di seguito viene illustrato il rendering di questo esempio.
Le figure seguenti mostrano come viene eseguito il rendering rispettivamente delle decorazioni Linea sopra, Linea di base e Sottolineato.
Opzioni tipografiche
La proprietà Typography è esposta da gran parte del contenuto correlato al flusso inclusi TextElement, FlowDocument, TextBlock e TextBox. Questa proprietà è utilizzata per controllare le caratteristiche tipografiche/variazioni di testo (ad esempio il maiuscoletto o maiuscolo, pedici e sottoscrizioni, ecc.).
Nell'esempio riportato di seguito viene illustrato come impostare l'attributo Typography, utilizzando Paragraph come elemento di esempio.
<Paragraph
TextAlignment="Left"
FontSize="18"
FontFamily="Palatino Linotype"
Typography.NumeralStyle="OldStyle"
Typography.Fraction="Stacked"
Typography.Variants="Inferior"
>
<Run>
This text has some altered typography characteristics. Note
that use of an open type font is necessary for most typographic
properties to be effective.
</Run>
<LineBreak/><LineBreak/>
<Run>
0123456789 10 11 12 13
</Run>
<LineBreak/><LineBreak/>
<Run>
1/2 2/3 3/4
</Run>
</Paragraph>
Nella figura riportata di seguito viene illustrato il rendering di questo esempio.
Di seguito viene invece illustrato il rendering di un esempio simile con proprietà tipografiche predefinite.
Nell'esempio riportato di seguito viene illustrato come impostare la proprietà Typography a livello di codice.
Paragraph par = new Paragraph();
Run runText = new Run(
"This text has some altered typography characteristics. Note" +
"that use of an open type font is necessary for most typographic" +
"properties to be effective.");
Run runNumerals = new Run("0123456789 10 11 12 13");
Run runFractions = new Run("1/2 2/3 3/4");
par.Inlines.Add(runText);
par.Inlines.Add(new LineBreak());
par.Inlines.Add(new LineBreak());
par.Inlines.Add(runNumerals);
par.Inlines.Add(new LineBreak());
par.Inlines.Add(new LineBreak());
par.Inlines.Add(runFractions);
par.TextAlignment = TextAlignment.Left;
par.FontSize = 18;
par.FontFamily = new FontFamily("Palatino Linotype");
par.Typography.NumeralStyle = FontNumeralStyle.OldStyle;
par.Typography.Fraction = FontFraction.Stacked;
par.Typography.Variants = FontVariants.Inferior;
Per ulteriori informazioni sulla tipografia, vedere Funzionalità tipografiche di Windows Presentation Foundation.
Vedere anche
Attività
Concetti
Ottimizzazione delle prestazioni: testo
Funzionalità tipografiche di Windows Presentation Foundation
Cenni preliminari sul modello di contenuto TextElement
Cenni generali sul controllo RichTextBox
Documenti di Windows Presentation Foundation
Cenni preliminari sull'elemento Table
Cenni preliminari sulle annotazioni
Altre risorse
Esempi di elementi di contenuto del flusso
Argomenti sulle procedure relative a elementi di contenuto del flusso