Capitolo 3: Controlli e XAML
Introduzione
Capitolo 1: Modello di applicazione "Longhorn"
Capitolo 2: Creazione di un'applicazione "Longhorn"
Capitolo 3: Controlli e XAML
Rettore Di Brent
Consulenza per il gufo saggio
Dicembre 2003
Contenuto
Elementi XAML
Pannelli XAML
Controlli
Risorse e stili
Grafica e animazioni
Servizi documenti
Riepilogo
Come si è visto nel capitolo 2, le applicazioni della piattaforma Longhorn in genere sono costituite da un oggetto Application e da un set di pagine dell'interfaccia utente scritte in un linguaggio di markup dichiarativo denominato XAML.
L'oggetto Application è un singleton e persiste durante la durata dell'applicazione. Consente alla logica dell'applicazione di gestire gli eventi di primo livello e condividere codice e stato tra le pagine. L'oggetto Application determina anche se l'applicazione è un'applicazione a finestra singola o un'applicazione di spostamento.
In genere si scrive ogni pagina dell'interfaccia utente usando un dialetto xml denominato Extensible Application Markup Language (XAML). Ogni pagina è costituita da elementi XAML, nodi di testo e altri componenti organizzati in un albero gerarchico. La relazione gerarchica di questi componenti determina il rendering e il comportamento della pagina.
È anche possibile considerare una pagina XAML come descrizione di un modello a oggetti. Quando il runtime crea la pagina, crea un'istanza di ognuno degli elementi e dei nodi descritti nel documento XAML e crea un modello a oggetti equivalente in memoria. È possibile modificare questo modello a oggetti a livello di codice, ad esempio è possibile aggiungere e rimuovere elementi e nodi per causare il rendering e il comportamento della pagina in modo diverso.
Fondamentalmente, una pagina XAML descrive le classi che il runtime deve creare, i valori delle proprietà e i gestori eventi per le istanze delle classi e una gerarchia di modelli a oggetti, ovvero l'istanza è l'elemento padre di un'altra istanza.
Tutti i documenti XAML sono documenti XML ben formati che usano un set definito di nomi di elementi. Pertanto, tutte le regole relative alla formazione di documenti XML ben formati si applicano ugualmente ai documenti XAML. Ad esempio, il documento deve contenere un singolo elemento radice; tutti i nomi degli elementi sono distinzione tra maiuscole e minuscole; una definizione di elemento non può sovrapporsi a un'altra definizione di elemento, ma deve contenere interamente e così via. Se non si ha familiarità con la sintassi XML, è ora un momento eccellente per imparare.
Elementi XAML
Ogni pagina XAML contiene uno o più elementi che controllano il layout e il comportamento della pagina. Si dispone di questi elementi gerarchicamente in un albero. Ogni elemento ha un solo elemento padre. Gli elementi possono in genere avere un numero qualsiasi di elementi figlio. Tuttavia, alcuni tipi di elemento, ad esempio la barra di scorrimento, non hanno elementi figlio; e altri tipi di elemento, ad esempio Border, possono avere un singolo elemento figlio.
Ogni nome di elemento corrisponde al nome di una classe gestita. L'aggiunta di un elemento a un documento XAML causa la creazione di un'istanza della classe corrispondente. Ad esempio, il markup seguente rappresenta un elemento DockPanel radice con un singolo elemento Table figlio. L'elemento Table contiene tre elementi Row figlio. Ogni elemento Row contiene tre elementi figlio e alcuni di essi hanno nodi di testo figlio.
<Border xmlns="https://schemas.microsoft.com/2003/xaml"
Background="BlanchedAlmond">
<DockPanel>
<Table>
<Body>
<Row>
<Cell><Button/></Cell>
<Cell><Text>Item</Text></Cell>
<Cell><Text>Price</Text></Cell>
</Row>
<Row>
<Cell><CheckBox Checked="true"/></Cell>
<Cell><TextBox Height="50">Nissan 350Z</TextBox></Cell>
<Cell><TextBox Height="50">29.95</TextBox></Cell>
</Row>
<Row>
<Cell><CheckBox/></Cell>
<Cell><TextBox Height="50">Porsche Boxster</TextBox></Cell>
<Cell><TextBox Height="50">9.95</TextBox></Cell>
</Row>
</Body>
</Table>
</DockPanel>
</Border>
Questo documento XAML crea una gerarchia di oggetti come illustrato nella figura 3-1 e la visualizzazione illustrata nella figura 3-2.
Figura 3-1. Modello a oggetti pagina XAML di esempio
Figura 3-2. Visualizzazione dal codice XAML precedente (fare clic per un'immagine più grande)
È possibile accedere a gran parte delle funzionalità di tali oggetti usando solo il markup. Usando solo il markup, è possibile eseguire una delle operazioni seguenti:
- Descrivere un set gerarchico di oggetti che il runtime creerà un'istanza
- Impostare le proprietà dell'oggetto su valori noti in modo statico
- Impostare le proprietà dell'oggetto su valori recuperati da un'origine dati
- Causare l'archiviazione dei valori delle proprietà modificati nell'origine dati
- Modificare ripetutamente il valore di una proprietà nel tempo
- Associare un gestore eventi all'evento di un oggetto
Tuttavia, anche se è possibile creare alcune interfacce utente incredibili usando solo il markup, è anche possibile accedere alle funzionalità di un elemento a livello di codice usando il modello a oggetti XAML. Il modello a oggetti consente di modificare ogni aspetto degli elementi in una pagina. Offre in realtà funzionalità aggiuntive che non sono accessibili tramite XAML.
Ogni elemento XAML deriva da System.Windows.UIElement o System.Windows.ContentElement e quindi tutti gli elementi hanno una serie di funzionalità comuni. Gli elementi possono essere raggruppati nelle quattro categorie di base seguenti:
- I controlli derivano da System.Windows.Control e gestiscono l'interazione dell'utente.
- I pannelli sono controlli specializzati che derivano da System.Windows.Panel e gestiscono il layout della pagina e fungono da contenitori per gli elementi.
- Gli elementi di formattazione del testo derivano da System.Windows.TextElement e gestiscono la formattazione del testo e la struttura del documento.
- Le forme gestiscono forme grafiche vettoriali.
Pannelli XAML
Una pagina XAML inizia in genere con un elemento del pannello. Il pannello è un contenitore per il contenuto di una pagina e controlla la posizione e il rendering di tale contenuto. Infatti, quando si visualizza qualsiasi elemento usando XAML, un pannello è sempre coinvolto, anche se talvolta è implicito anziché uno descritto in modo esplicito. Un pannello può contenere altri pannelli, consentendo di partizionare la superficie di visualizzazione in aree, ognuna controllata dal pannello.
Nella piattaforma Longhorn sono disponibili sei classi di pannello predefinite:
- Un elemento Canvas posiziona in modo esplicito ogni elemento figlio usando coordinate relative all'area Canvas .
- Un DockPanel inserisce i suoi figli nella parte superiore, in basso, in basso, a sinistra, a destra o al centro del pannello. Quando si assegnano più elementi figlio alla stessa area, un DockPanel li dispone orizzontalmente o verticalmente all'interno di tale area.
- FlowPanel dispone i relativi elementi figlio in base alle proprietà di interruzione e allineamento della linea. Quando il contenuto supera la lunghezza di una singola riga, il pannello interrompe le righe, esegue il wrapping delle righe e allinea il contenuto in modo appropriato.
- TextPanel esegue il rendering di più righe di testo in più formati di testo. In genere verrà usato solo quando è necessario un layout di testo complesso. Per la maggior parte dei casi, si userà l'elemento Text leggero per il supporto di testo di base.
- GridPanel è un elemento leggero che dispone i relativi elementi figlio in righe e colonne che formano una griglia. È utile per la creazione di tabelle semplici, ma dispone di funzionalità limitate. Usare il controllo Tabella per il layout di tabella complesso.
- FixedPanel posiziona i relativi elementi figlio in una pagina di layout fissa. Gli elementi nelle pagine di layout fisso hanno sempre la stessa posizione e impaginazione indipendentemente dalla risoluzione del dispositivo o dalle dimensioni della finestra.
In genere, questi pannelli forniscono funzionalità sufficienti per la maggior parte degli sviluppatori. Tuttavia, è anche possibile creare classi del pannello personalizzate che posizionano e visualizzano il contenuto in modo specializzato.
Canvas
Il pannello Canvas offre una notevole flessibilità per quanto riguarda la posizione e l'ordinamento degli elementi sullo schermo. Consente di specificare la posizione per ogni elemento figlio e, quando gli elementi si sovrappongono, è possibile specificare l'ordine in cui l'area di disegno disegna gli elementi sovrapposti modificando l'ordine in cui vengono visualizzati gli elementi nel markup.
Il markup seguente produce tre grafici sovrapposti, come si vede nella figura 3-1: un rettangolo verde con un bordo arancione, un'ellisse giallo translucente con un bordo blu e alcuni testo centrati nel rettangolo. (Il pensiero di non scrivere mai più un gestore WM_PAINT per disegnare cose come questa porta lacrime ai miei occhi . . lacrime di gioia che ho avuto da aggiungere!) Il framework disegna le forme nell'ordine presentato, quindi il testo viene visualizzato sul rettangolo.
<Canvas xmlns="https://schemas.microsoft.com/2003/xaml" >
<Rectangle
Fill="#33CC66"
Width="2in" Height="1in"
Canvas.Top="25" Canvas.Left="50"
StrokeThickness="6px" Stroke="Orange" />
<Ellipse
Fill="yellow"
CenterX="1.5in" CenterY="1.1in"
RadiusX=".5in" RadiusY="1in"
StrokeThickness="4px" Stroke="Blue" />
<Text
Canvas.Top="50" Canvas.Left="60" Foreground="#000000"
FontWeight="Bold" FontFamily="Arial"
FontStyle="Normal" FontSize="25">Hello Shapes!</Text>
</Canvas>
Figura 3-3. Esempio di utilizzo del pannello Canvas
DockPanel
Il pannello DockPanel dispone gli elementi figlio orizzontalmente o verticalmente, rispetto all'uno all'altro. La classe DockPanel esamina la proprietà Dock di ogni elemento figlio per determinare come allineare l'elemento lungo i bordi del pannello. È possibile impostare la proprietà Dock su uno dei cinque valori: Top, Bottom, Left, Right o Fill.
Ad esempio, un pannello allinea il primo elemento figlio con la relativa proprietà Dock uguale a Top sul bordo superiore del pannello. Il pannello allinea quindi l'elemento figlio successivo con la relativa proprietà Dock uguale a Top appena sotto l'elemento precedente. Il pannello allinea in modo analogo gli elementi figlio con la relativa proprietà Dock impostata su Bottom, Left o Right. L'impostazione della proprietà Dock dell'ultimo elemento figlio su Fill lo fa occupare tutto lo spazio rimanente in DockPanel. Non seguire mai un elemento Dock="Fill" con altri elementi perché gli elementi successivi non saranno visibili. Il valore predefinito della proprietà Dock è Left, quindi quando non si imposta la proprietà Dock per un elemento, si sovrappone orizzontalmente a sinistra.
La proprietà Dock è una proprietà associata, definita dalla classe DockPanel , ma la imposti su un elemento figlio come segue:
<child DockPanel.Dock="Top"/>
Oppure nel codice:
DockPanel.SetDock(child, Dock.Top)
Il markup seguente usa un pannello DockPanel e cinque pannelli Canvas per creare un'interfaccia utente comunemente vista. DockPanel allinea le prime due aree di disegno sulla parte superiore di DockPanel. Allinea il terzo canvas sul bordo inferiore di DockPanel, il quarto rispetto al bordo sinistro e il quinto canvas riempie lo spazio rimanente. È possibile inserire un menu nel pannello superiore e una barra degli strumenti nel pannello appena sotto il menu. Questa decisione lascia il pannello sinistro per una visualizzazione albero, il pannello inferiore per una barra di stato e il pannello rimanente per la visualizzazione dettagliata degli elementi selezionati, come si può vedere nella figura 3-4.
<Border xmlns="https://schemas.microsoft.com/2003/xaml"
Background="White">
<DockPanel>
<Border Width="500" DockPanel.Dock="Top"
BorderThickness="2,2,2,2" BorderBrush="Black" Background="#87ceeb" >
<Text>Dock = "Top"</Text>
</Border>
<Border Width="500" DockPanel.Dock="Top"
BorderThickness="2,2,2,2" BorderBrush="Black" Background="#87ceeb" >
<Text>Dock = "Top"</Text>
</Border>
<Border Width="500" DockPanel.Dock="Bottom"
BorderThickness="2,2,2,2"
BorderBrush="Black" Background="#ffff99" >
<Text>Dock = "Bottom"</Text>
</Border>
<Border Width="200" DockPanel.Dock="Left"
BorderThickness="2,2,2,2" BorderBrush="Black" Background="#98fb98" >
<Text>Dock = "Left"</Text>
</Border>
<Border Width="300" DockPanel.Dock="Fill"
BorderThickness="2,2,2,2" BorderBrush="Black" Background="White" >
<Text>Dock = "Fill"</Text>
</Border>
</DockPanel>
</Border>
Figura 3-4. Esempio di uso del pannello DockPanel
FlowPanel
Il pannello FlowPanel offre una serie di funzionalità di layout automatico e consente presentazioni complesse di testo e grafica. Le dimensioni del pannello vengono definite usando le relative proprietà Width e Height . Il pannello visualizza quindi i relativi elementi figlio in modo da usare al meglio lo spazio del pannello, il wrapping e l'allineamento degli elementi in base alle esigenze. La direzione del flusso predefinita per flowPanel è da sinistra a destra e dall'alto verso il basso.
Nell'esempio di markup seguente viene illustrato come FlowPanel interrompe e esegue il wrapping del contenuto. FlowPanel contiene quattro canvas quadrati di 1 pollice. FlowPanel tenta di visualizzare i relativi elementi figlio da sinistra a destra e dall'alto verso il basso.
<Border xmlns="https://schemas.microsoft.com/2003/xaml" Background="White">
<FlowPanel>
<Border Background="Red" Width="1in" Height="1in"/>
<Border Background="Green" Width="1in" Height="1in"/>
<Border Background="Blue" Width="1in" Height="1in"/>
<Border Background="Yellow" Width="1in" Height="1in"/>
</FlowPanel>
</Border>
La figura 3-3 mostra l'output quando FlowPanel può adattare tutti gli elementi su una singola riga. La figura 3-4 illustra il wrapping di FlowPanel dell'ultimo elemento in una nuova riga. La figura 3-5 mostra il peggiore caso in cui FlowPanel deve posizionare ogni elemento sulla propria riga. La figura 3-6 mostra l'ultimo ritorno a capo automatico in una nuova riga e nella figura 3-7 ogni elemento viene disposto su una nuova riga.
Figura 3-5. FlowPanel interrompe le righe solo quando necessario.
Figura 3-6. Pannello FlowPanel che esegue il wrapping dell'ultimo elemento in una nuova riga
Figura 3-7. Pannello FlowPanel che esegue il wrapping di ogni elemento in una nuova riga
TextPanel
Il pannello TextPanel formatta, ridimensiona e disegna testo. Questa classe panel supporta più righe di testo e più formati di testo. In genere si userà la classe TextPanel quando è necessario un supporto di layout complesso. Tuttavia, quando è necessaria solo una visualizzazione di testo semplice, è preferibile usare l'elemento Text .
Nell'esempio di markup seguente viene illustrato il modo in cui TextPanel interrompe e esegue il wrapping del contenuto. TextPanel regola il numero di colonne e l'altezza di ogni colonna durante il ridimensionamento della finestra.
<Border xmlns="https://schemas.microsoft.com/2003/xaml" Background="White">
<TextPanel
ColumnCount="3"
ColumnWidth="200px"
ColumnGap="25px"
ColumnRuleWidth="5px"
ColumnRuleBrush="blue">
<Block Background="LightGray">
<Inline FontFamily="Arial" FontWeight="Bold"
FontSize="16pt">Transcript of the
<Italic>Nicolay Draft</Italic>
of the Gettysburg Address.
</Inline>
</Block>
§
</TextPanel>
</Border>
La figura 3-8 mostra l'output risultante.
Figura 3-8. TextPanel con più caratteristiche, colonne e formattazione dei tipi di carattere
GridPanel
Il pannello GridPanel visualizza i dati tabulari. GridPanel supporta molte proprietà che è possibile usare per personalizzare il layout dei dati tabulari. Ad esempio, è possibile impostare le proprietà Columns e Rows per controllare il numero di colonne e righe nella griglia. Analogamente, le proprietà ColumnStyles e RowStyles consentono di impostare una raccolta di proprietà che GridPanel si applica rispettivamente alle righe e alle colonne.
GridPanel dispone gli elementi figlio in ordine, a partire dalla cella superiore sinistra e spostandosi a destra fino alla fine della riga. Un elemento figlio può accettare più colonne se si imposta la proprietà GridPanel.ColumnSpan sull'elemento figlio. Analogamente, GridPanel.RowSpan consente a un elemento figlio di estendersi su più righe.
Il markup seguente mostra un'interfaccia utente calculator simile all'utilità Calcolatrice di Windows.
<Border xmlns="https://schemas.microsoft.com/2003/xaml" Background="#DEE7F7">
<DockPanel Dock="Left">
<Border BorderThickness="0,0,0,0">
<!-- Padding="10, 10, 10, 10" -->
<GridPanel Columns="7">
<GridPanel.ColumnStyles>
<Column Width="16%"/>
<Column Width="4%"/>
<Column Width="16%"/>
<Column Width="16%"/>
<Column Width="16%"/>
<Column Width="16%"/>
<Column Width="16%"/>
</GridPanel.ColumnStyles>
<GridPanel.RowStyles>
<Row Height="25"/>
<Row Height="10"/>
<Row Height="35"/>
<Row Height="7"/>
<Row Height="35"/>
<Row Height="35"/>
<Row Height="35"/>
<Row Height="35"/>
</GridPanel.RowStyles>
<Border GridPanel.ColumnSpan="7" BorderBrush="#DEE7F7"
BorderThickness="2,2,2,2" Background="White">
<Text HorizontalAlignment="right"
ID="CalcText">0.</Text>
</Border>
<Text GridPanel.ColumnSpan="7"/>
<Border BorderThickness="0,0,0,0">
<GridPanel>
<Border BorderBrush="#DEE7F7" BorderThickness="2,2,2,2">
<Text Width="16%"
HorizontalAlignment="center"></Text>
</Border>
</GridPanel>
</Border>
<Text Width="4%"/>
<DockPanel GridPanel.ColumnSpan="5" Dock="Left">
<Button Width="33.33%" Foreground="Red">Backspace</Button>
<Button Width="33.33%" Foreground="Red">CE</Button>
<Button Width="33.33%" Foreground="Red">C</Button>
</DockPanel>
<Text GridPanel.ColumnSpan="7"/>
<Button Foreground="Red">MC</Button>
<Text/>
<Button Foreground="Blue">7</Button>
<Button Foreground="Blue">8</Button>
<Button Foreground="Blue">9</Button>
<Button Foreground="Red">/</Button>
<Button Foreground="Blue">sqrt</Button>
<Button Foreground="Red">MR</Button>
<Text/>
<Button Foreground="Blue">4</Button>
<Button Foreground="Blue">5</Button>
<Button Foreground="Blue">6</Button>
<Button Foreground="Red">*</Button>
<Button Foreground="Blue">%</Button>
<Button Foreground="Red">MS</Button>
<Text/>
<Button Foreground="Blue">1</Button>
<Button Foreground="Blue">2</Button>
<Button Foreground="Blue">3</Button>
<Button Foreground="Red">-</Button>
<Button Foreground="Blue">1/x</Button>
<Button Foreground="Red">M+</Button>
<Text/>
<Button Foreground="Blue">0</Button>
<Button Foreground="Blue">+/-</Button>
<Button Foreground="Blue">.</Button>
<Button Foreground="Red">+</Button>
<Button Foreground="Red">=</Button>
</GridPanel>
</Border>
</DockPanel>
</Border>
La figura 3-9 mostra l'output risultante.
Figura 3-9. GridPanel come calcolatrice
FixedPanel
Il pannello FixedPanel consente di specificare le posizioni e le dimensioni esatte di ogni elemento. Gli elementi in fixedPanel verranno sempre visualizzati nella stessa posizione e dimensione in tutti i dispositivi. Il pannello FixedPanel verrà illustrato più avanti in questo capitolo nella sezione "Document Layout Services".
Controlli
XAML include tutti i controlli previsti da Windows, ovvero pulsanti, caselle di controllo, pulsanti di opzione, caselle di opzione, caselle di riepilogo, caselle combinate, menu, barre di scorrimento, dispositivi di scorrimento e così via. Questo esempio illustra alcuni dei controlli comuni forniti in Longhorn. È possibile visualizzare i risultati nella figura 3-10.
<Border
xmlns="https://schemas.microsoft.com/2003/xaml"
xmlns:def="Definition"
Background="BlanchedAlmond"
>
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="File">
<MenuItem Header="New" />
<MenuItem Header="Open" />
</MenuItem>
<MenuItem Header="Edit">
<MenuItem Header="Cut"/>
<MenuItem Header="Copy"/>
<MenuItem Header="Paste"/>
</MenuItem>
</Menu>
<FlowPanel>
<Button> Button </Button>
<Border Width="15"/>
<CheckBox Checked="true"> CheckBox </CheckBox>
<Border Width="15"/>
<RadioButtonList>
<RadioButton> RadioButton 1 </RadioButton>
<RadioButton Checked="true"> RadioButton 2 </RadioButton>
<RadioButton> RadioButton 3 </RadioButton>
</RadioButtonList>
<Border Width="15"/>
<ListBox>
<ListItem> ListItem 1 </ListItem>
<ListItem> ListItem 2 </ListItem>
<ListItem> ListItem 3 </ListItem>
</ListBox>
<Border Width="15"/>
<ComboBox>
<ListItem> ListItem 1 </ListItem>
<ListItem> ListItem 2 </ListItem>
<ListItem> ListItem 3 </ListItem>
</ComboBox>
<Border Width="15"/>
<DockPanel>
<VerticalSlider DockPanel.Dock="Top" Height="200"
Minimum="0" Maximum="255" Value="75"
SmallChange="1" LargeChange="16"/>
<Text DockPanel.Dock="Bottom">Slider</Text>
</DockPanel>
<Border Width="15"/>
<DockPanel>
<VerticalScrollBar DockPanel.Dock="Top"
Minimum="0" Maximum="255" Value="125" Height="200"
SmallChange="1" LargeChange="16"/>
<Text DockPanel.Dock="bottom">ScrollBar</Text>
</DockPanel>
<Border Width="15"/>
<TextBox> TextBox </TextBox>
</FlowPanel>
</DockPanel>
</Border>
Figura 3-10. Esempio di controlli XAML
XAML consente anche di combinare elementi e controlli per creare effetti avanzati. Chiamiamo questa combinazione di elementi di composizione del controllo, ed è uno degli aspetti più potenti di Longhorn. Ad esempio, per creare un pulsante con un'immagine, inserire un elemento Image all'interno di Button:
<Button>
<Image Source="tulip.jpg"/>
</Button>
Per avere sia un'immagine che un testo in Button, come si può vedere nella figura 3-11, usiamo il nostro vecchio amico DockPanel:
<Button>
<DockPanel>
<Image Source="tulip.jpg"/>
<Text DockPanel.Dock="fill" VerticalAlignment="center"> Button
<Italic>with Image!</Italic>
</Text>
</DockPanel>
</Button>
Figura 3-11. Pulsante con un'immagine e un testo
È possibile inserire praticamente qualsiasi elemento all'interno di qualsiasi elemento, incluso questo strano esempio di checkBox all'interno di un pulsante:
<Button>
<CheckBox Checked="true"> CheckBox </CheckBox>
</Button>
La composizione è abbastanza potente che molti dei controlli Longhorn vengono effettivamente definiti usando la composizione. Ad esempio, un controllo ScrollBar è in realtà due pulsanti e un dispositivo di scorrimento, più una logica del gestore eventi per collegarli tra loro.
XAML include anche alcuni controlli "primitive", che vengono usati principalmente con la composizione del controllo per creare effetti più grandi. Ad esempio , ScrollViewer accetta un elemento figlio (in genere un pannello) e aggiunge le barre di scorrimento. In questo esempio viene inserito un elenco molto grande di elementi CheckBox all'interno di un controllo ScrollViewer, che prima di Longhorn richiedeva un controllo separato, ad esempio checkedListBox di Windows Forms:
<Border BorderThickness="1" BorderBrush="black">
<ScrollViewer Height="100" Width="200">
<GridPanel Columns="1">
<CheckBox Checked="true"> CheckBox 1</CheckBox>
<CheckBox Checked="true"> CheckBox 2</CheckBox>
<CheckBox Checked="true"> CheckBox 3</CheckBox>
<CheckBox Checked="true"> CheckBox </CheckBox>
<CheckBox Checked="true"> CheckBox </CheckBox>
<CheckBox Checked="true"> CheckBox </CheckBox>
<CheckBox Checked="true"> CheckBox </CheckBox>
<CheckBox Checked="true"> CheckBox </CheckBox>
</GridPanel>
</ScrollViewer>
</Border>
Risorse e stili
XAML offre funzionalità molto avanzate per personalizzare l'aspetto dell'applicazione, tramite entità note come stili. Tuttavia, prima di approfondire questo argomento, è necessario conoscere le risorse. Il termine risorse usate in questo contesto si riferisce semplicemente a un modo per riutilizzare oggetti e valori comunemente definiti. Ecco un esempio:
<Border
xmlns="https://schemas.microsoft.com/2003/xaml"
xmlns:def="Definition"
Background="BlanchedAlmond"
>
<FlowPanel>
<FlowPanel.Resources>
<SolidColorBrush def:Name="MyColor" Color="Gold"/>
</FlowPanel.Resources>
<Button Background="{MyColor}"/>
<Ellipse Fill="{MyColor}"/>
</FlowPanel>
</Border>
Questo codice definisce una nuova risorsa denominata MyColor, il cui tipo è SolidColorBrush e il valore è Gold. Questa risorsa fa parte della raccolta Resources di FlowPanel. Ogni elemento ha una raccolta Resources . Puoi definire le risorse su qualsiasi elemento desiderato, ma più spesso le inserisci solo sull'elemento radice, in questo caso FlowPanel.
Dopo aver definito una risorsa, è possibile fare riferimento alla risorsa in un valore della proprietà inserendo il nome della risorsa tra parentesi graffe, come illustrato di seguito:
<Button Background="{MyColor}"/>
Quando il processore XAML vede {MyColor} in questo esempio, controlla prima di tutto la raccolta Resources del pulsante. Poiché Button non ha una definizione di MyColor (la relativa raccolta Resources è vuota), controlla l'elemento padre di Button, ovvero FlowPanel.
Un tipo particolarmente utile di risorsa è uno stile. Style è sia il nome della classe che il nome di una proprietà di tutti gli elementi. Un oggetto Style definisce le proprietà da impostare su un elemento, che quindi usa tale stile designato. Questo esempio definisce uno stile denominato MyStyle e lo applica a un pulsante:
<Border
xmlns="https://schemas.microsoft.com/2003/xaml"
xmlns:def="Definition"
Background="BlanchedAlmond"
>
<FlowPanel>
<FlowPanel.Resources>
<Style def:Name="MyStyle">
<Button Background="Red" FontSize="24"/>
</Style>
</FlowPanel.Resources>
<Button>Normal</Button>
<Button Style="{MyStyle}">Styled</Button>
</FlowPanel>
</Border>
È anche possibile definire una risorsa Style senza nome, che diventa lo stile predefinito dell'elemento per gli elementi in cui non si specifica una proprietà Style esplicita. In questo esempio viene aggiunto uno stile predefinito all'esempio precedente:
<Border
xmlns="https://schemas.microsoft.com/2003/xaml"
xmlns:def="Definition"
Background="BlanchedAlmond"
>
<FlowPanel>
<FlowPanel.Resources>
<Style>
<Button Background="Green" FontSize="15"/>
</Style>
<Style def:Name="MyStyle">
<Button Background="Red" FontSize="24"/>
</Style>
</FlowPanel.Resources>
<Button>Normal</Button>
<Button Style="{MyStyle}">Styled</Button>
</FlowPanel>
</Border>
È possibile eseguire un tipo di ereditarietà dello stile impostando la proprietà BasedOn della classe Style . Se si fa riferimento alla nuova classe Style , verranno impostate tutte le proprietà del vecchio stile , oltre alle proprietà aggiuntive specificate. Nell'esempio seguente vengono definiti due stili: il primo imposta la proprietà Background e il secondo, in base al primo, imposta la proprietà FontSize .
<Border
xmlns="https://schemas.microsoft.com/2003/xaml"
xmlns:def="Definition"
Background="BlanchedAlmond"
>
<FlowPanel>
<FlowPanel.Resources>
<Style def:Name="Style1">
<Button Background="Red"/>
</Style>
<Style def:Name="Style2" BasedOn="{Style1}">
<Button FontSize="24"/>
</Style>
</FlowPanel.Resources>
<Button Style="{Style1}">Style 1</Button>
<Button Style="{Style2}">Style 2</Button>
</FlowPanel>
</Border>
È anche possibile che uno Stile imposti le proprietà in modo condizionale, usando una funzionalità nota come trigger di proprietà. Style ha una proprietà denominata VisualTriggers, che è un insieme di PropertyTriggers. Ogni PropertyTrigger specifica una condizione utilizzando le proprietà Property e Value e contiene una raccolta di istruzioni Set . Quando la proprietà dell'elemento con stile corrisponde a tale valore, vengono applicate le istruzioni Set e quando la condizione non è più true, i valori non vengono più applicati, come se non fossero mai stati impostati al primo posto. In questo esempio vengono usati trigger di proprietà per rendere verde il pulsante quando il mouse si trova sul pulsante e rosso in caso contrario:
<Border
xmlns="https://schemas.microsoft.com/2003/xaml"
xmlns:def="Definition"
Background="BlanchedAlmond"
>
<FlowPanel>
<FlowPanel.Resources>
<Style def:Name="Style1">
<Button Background="Red"/>
<Style.VisualTriggers>
<PropertyTrigger Property="IsMouseOver" Value="true">
<Set PropertyPath="Background" Value="Green"/>
</PropertyTrigger>
</Style.VisualTriggers>
</Style>
</FlowPanel.Resources>
<Button Style="{Style1}">Style 1</Button>
</FlowPanel>
</Border>
Molti controlli XAML usano la composizione del controllo. Combinano un numero di controlli più piccoli per creare un controllo più grande e più complicato. Gli stili ti consentono anche di modificare questo! Specificando una composizione diversa, è possibile ridefinire completamente l'aspetto di un controllo mantenendo comunque il comportamento.
Dopo aver dichiarato l'elemento di stile e le relative proprietà, il <tag Style.VisualTree> specifica all'interno dello stile gli elementi da comporre per creare il controllo più grande. È possibile impostare le proprietà degli elementi figlio come di consueto e assegnare a tali figli i propri figli. È anche possibile usare l'aliasing delle proprietà per impostare i valori delle proprietà. Ad esempio, Name1="*Alias(Target=Name2)" imposta la proprietà Name1 del figlio sulla proprietà Name2 del controllo più grande. Nell'esempio seguente viene creato uno stile per Button che modifica la composizione per ottenere un aspetto arrotondato, come si può vedere nella figura 3-12. Le proprietà Sfondo e Contenuto del pulsante vengono aliasate in punti appropriati nell'albero visivo.
<Border Background="white"
xmlns="https://schemas.microsoft.com/2003/xaml"
xmlns:def="Definition">
<FlowPanel>
<FlowPanel.Resources>
<Style def:Name="RoundButton">
<Button FontSize="20"/>
<Style.VisualTree>
<Canvas>
<Rectangle ID="MainRect"
RadiusX="10" RadiusY="10"
Fill="*Alias(Target=Background)"
Width="100%" Height="100%" />
<FlowPanel Width="100%" Height="100%" >
<ContentPresenter
ContentControl.Content="*Alias(Target = Content)"
Margin="15,3,15,5"/>
</FlowPanel>
</Canvas>
</Style.VisualTree>
</Style>
</FlowPanel.Resources>
<Button Style="{RoundButton}">
standard RoundButton
</Button>
<Button Background="red" Style="{RoundButton}">
red RoundButton
</Button>
<Button>
standard button
</Button>
<Button Background="red">
red standard button
</Button>
</FlowPanel>
</Border>
Figura 3-12. Un paio di pulsanti RoundButton e standard in un FlowPanel
Grafica e animazioni
XAML offre un supporto completo per le forme di disegno, trasformando lo stato di un oggetto e animando quasi qualsiasi proprietà di un oggetto. Si usano gli elementi Shape per il disegno, trasformare gli elementi per modificare una proprietà o un oggetto e gli elementi Animation per modificare una proprietà di un oggetto nel corso del tempo.
Forme
XAML fornisce un set di elementi Shape per il disegno, che includono Ellipse, Line, Rectangle, Path, Polygon e Polyline. Una forma ha un riempimento, ovvero il colore di sfondo e un tratto, ovvero il colore della struttura. Riempimento e Tratto predefinito su trasparente, quindi assicurarsi di impostare almeno uno di essi! La proprietà StrokeWidth controlla lo spessore della struttura.
Le forme non possono avere elementi figlio. In genere si inserisce forme all'interno di un canvas, quindi la prima forma nel markup sarà la prima disegnata. Questo esempio illustra alcune forme di base, che è anche possibile vedere nella figura 3-13:
<Border
xmlns="https://schemas.microsoft.com/2003/xaml"
xmlns:def="Definition"
Background="BlanchedAlmond"
>
<Canvas Height="400" Width="400">
<Ellipse CenterX="70" CenterY="75"
RadiusX="30" RadiusY="50"
Fill="yellow" Stroke="red" StrokeThickness="15"/>
<Rectangle RectangleLeft="150" RectangleTop="20"
RectangleHeight="100" RectangleWidth="40"
Fill="lightBlue" Stroke="green"/>
<Line X1="20" Y1="220" X2="150" Y2="240"
Stroke="black" StrokeThickness="5"/>
<Polygon Points="220,140 270,240 170,240"
StrokeLineJoin="Round"
Stroke="black" StrokeThickness="20"/>
</Canvas>
</Border>
Figura 3-13. Varie forme in un'area di disegno
Finora, abbiamo usato solo colori a tinta unita con le proprietà Stroke e Fill . Ma in XAML, quasi ovunque sia possibile usare un colore che è possibile specificare un pennello. SolidColorBrush è il tipo di pennello usato finora, ma XAML supporta anche ImageBrush, LinearGradientBrush e RadialGradientBrush. ImageBrush ha una proprietà ImageSource che specifica il nome del file di immagine. SolidColorBrush ha una proprietà Color . LinearGradientBrush e RadialGradientBrush contengono un GradientStopCollection, che consente sfumature molto complicate. Questo esempio definisce quattro pennelli come risorse e li usa come tratto e riempimento dei puntini di sospensione. È possibile visualizzare l'aspetto della figura 3-14.
<Border
xmlns="https://schemas.microsoft.com/2003/xaml"
xmlns:def="Definition"
Background="BlanchedAlmond"
>
<Border.Resources>
<LinearGradientBrush def:Name="lineargradient" StartPoint="0,0"
EndPoint="1,1" >
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="Blue" Offset="0"/>
<GradientStop Color="white" Offset="1"/>
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<RadialGradientBrush def:Name="radialgradient" Focus="0.3,0.3">
<RadialGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="red" Offset="0"/>
<GradientStop Color="yellow" Offset="1"/>
</GradientStopCollection>
</RadialGradientBrush.GradientStops>
</RadialGradientBrush>
<ImageBrush def:Name="image" ImageSource="Tulip.jpg" TileMode="Tile"/>
<SolidColorBrush def:Name="solid" Color="gray"/>
</Border.Resources>
<Canvas Height="400" Width="400">
<Ellipse CenterX="100" CenterY="75"
RadiusX="90" RadiusY="50"
Fill="{lineargradient}" Stroke="{image}" StrokeThickness="15"/>
<Ellipse CenterX="300" CenterY="170"
RadiusX="50" RadiusY="150"
Fill="{radialgradient}" Stroke="{solid}" StrokeThickness="15"/>
</Canvas>
</Border>
Figura 3-14. Sfumature sul lavoro
Trasformazioni
XAML supporta diversi tipi di trasformazioni. RotateTransform ruota in base alla quantità della proprietà Angle . TranslateTransform sposta le cose in base alle proprietà X e Y . ScaleTransform ridurrà o estenderà in base alle proprietà ScaleX e ScaleY . SkewTransform slants cose, usando le proprietà AngleX, AngleY e Center . MatrixTransform supporta trasformazioni affine arbitrarie. Infine, TransformCollection è una trasformazione che consente di combinare diverse trasformazioni insieme.
Alcune classi, ad esempio Brush, hanno una proprietà Transform . Per altri casi, è possibile usare l'elemento TransformDecorator , con una proprietà Transform . TransformDecorator trasforma l'elemento figlio. (Come Border, può avere un solo figlio). TransformDecorator può contenere qualsiasi tipo di elemento figlio, tra cui forme, pannelli e controlli. Questo esempio usa per TransformDecorators. Il primo contiene un oggetto Ellipse e lo ruota a 45 gradi. Il secondo TransformDecorator contiene un ListBox e ruota e ridimensiona l'oggetto ListBox. È possibile visualizzare le forme come nella figura 3-15.
<Border
xmlns="https://schemas.microsoft.com/2003/xaml"
xmlns:def="Definition"
Background="BlanchedAlmond"
>
<Canvas Height="400" Width="400">
<TransformDecorator Transform="rotate 45">
<Ellipse CenterX="100" CenterY="75"
RadiusX="90" RadiusY="50"
Fill="white" Stroke="black" StrokeThickness="15"/>
</TransformDecorator>
<TransformDecorator Canvas.Top="200" Canvas.Left="100">
<TransformDecorator.Transform>
<TransformCollection>
<RotateTransform Angle="135"/>
<ScaleTransform ScaleX="2" ScaleY="4"/>
</TransformCollection>
</TransformDecorator.Transform>
<ListBox >
<ListItem> ListItem 1 </ListItem>
<ListItem> ListItem 2 </ListItem>
<ListItem> ListItem 3 </ListItem>
</ListBox>
</TransformDecorator>
</Canvas>
</Border>
Figura 3-15. ListBox e Ellipse asimmetria
Animazioni
XAML supporta anche animazioni. È possibile animare quasi tutte le proprietà. Alcune proprietà hanno una proprietà "Animations" corrispondente, ad esempio RuotaTransform.Angle e RotateTransform.AngleAnimations. In altri casi, è possibile assegnare una raccolta di animazioni a una proprietà usando la sintassi della proprietà composta. Ad esempio, vedere il codice seguente:
<Button>
<Button.Width>
… put animation collection here …
</Button.Width>
</Button>
Ogni tipo di proprietà ha una raccolta di animazioni separate. Il tipo di Button.Width è Length, quindi uno usa LengthAnimationCollection. Analogamente, gli oggetti di animazione stessi sono specifici del tipo della proprietà animata, ovvero lengthAnimationCollection contiene un set di oggetti LengthAnimation .
Gli oggetti animazione hanno una proprietà From e To , i cui tipi corrispondono al tipo della proprietà animata. L'oggetto animazione include anche proprietà Begin, Duration e End , misurate in secondi e controllano la tempistica dell'animazione. Begin supporta anche il valore Immediate e Duration supporta Indefinite. È possibile usare le proprietà RepeatCount e RepeatDuration per ripetere automaticamente l'animazione. La proprietà Fill specifica cosa accade alla proprietà dopo che l'animazione è finita. Fill="Hold" è uno dei valori più importanti; mantiene la proprietà nel valore end dell'animazione.
Le classi di animazione non fanno parte dello spazio dei nomi XAML predefinito, quindi sarà necessario usare ?< Mapping> e costrutti xmlns per caricare lo spazio dei nomi MSAvalon.Windows.Media.Animation. Poiché questo spazio dei nomi contiene classi da più DLL, sarà necessario un elemento separato <? Mapping> e xmlns per ogni DLL.
L'esempio successivo anima due proprietà, la proprietà RotateTransform.Angle e la proprietà Button.Width , che usano classi di entrambi gli spazi dei nomi di animazione. La figura 3-16 mostra il pulsante in momenti diversi.
<?Mapping XmlNamespace="animC" ClrNamespace="MSAvalon.Windows.Media.Animation"
Assembly="PresentationCore" ?>
<?Mapping XmlNamespace="animF" ClrNamespace="MSAvalon.Windows.Media.Animation"
Assembly="PresentationFramework" ?>
<Border
xmlns="https://schemas.microsoft.com/2003/xaml"
xmlns:animC="animC"
xmlns:animF="animF"
xmlns:def="Definition"
Background="BlanchedAlmond"
>
<Canvas Height="400" Width="400">
<TransformDecorator Canvas.Top="200" Canvas.Left="100">
<TransformDecorator.Transform>
<TransformCollection>
<RotateTransform Angle="135">
<RotateTransform.AngleAnimations>
<animC:DoubleAnimationCollection>
<animC:DoubleAnimation From="0" To="360" Duration="4"
AutoReverse="True"
RepeatDuration="Indefinite"/>
</animC:DoubleAnimationCollection>
</RotateTransform.AngleAnimations>
</RotateTransform>
</TransformCollection>
</TransformDecorator.Transform>
<ListBox >
<ListItem> ListItem 1 </ListItem>
<ListItem> ListItem 2 </ListItem>
<ListItem> ListItem 3 </ListItem>
</ListBox>
</TransformDecorator>
<Button Width="40" Canvas.Top="10" Canvas.Left="10">
<Button.Width>
<animF:LengthAnimationCollection>
<animF:LengthAnimation From="40" To="300"
AutoReverse="true" Begin="1" Duration="1.2"
RepeatDuration="Indefinite"/>
</animF:LengthAnimationCollection>
</Button.Width>
Button
</Button>
</Canvas>
</Border>
Figura 3-16. Visualizzazioni del pulsante animato in momenti diversi
Servizi documenti
La piattaforma Longhorn offre servizi completi che supportano una migliore esperienza di visualizzazione dei documenti online. Esistono due servizi principali: un controllo progettato per la visualizzazione, la impaginazione e lo spostamento attraverso il contenuto di un documento e i servizi di layout progettati per migliorare l'esperienza di lettura.
Controllo PageViewer
Usare il controllo PageViewer quando si vuole visualizzare un documento all'utente per la visualizzazione online. Il controllo PageViewer fornisce funzionalità di spostamento pagina e pagina. Il controllo formatta automaticamente il contenuto del documento in pagine separate. L'utente può passare direttamente a pagine diverse usando i controlli forniti dal visualizzatore di pagine.
Paginazione e spostamento
In genere, il contenuto online, ad esempio le pagine Web, era continuo. Un'interfaccia utente ha fornito barre di scorrimento per consentire di visualizzare il contenuto che non è riuscito a adattarsi all'area visibile. In effetti, si "scorre" la finestra di visualizzazione alla posizione nel documento che si desidera visualizzare.
Con la paginazione, si suddivide il contenuto del documento in una o più pagine singole, simili a un libro. La piattaforma Longhorn offre supporto per il contenuto impaginato, inclusi diversi controlli che consentono di visualizzare e esplorare il contenuto visualizzato come pagine discrete. Longhorn offre inoltre un'interfaccia di programmazione dell'applicazione impaginazione (API) per estendere queste funzionalità e fornire supporto avanzato per le applicazioni di impaginazione personalizzate.
Il controllo PageViewer è effettivamente un controllo complesso creato da controlli più piccoli usando tecniche di composizione del controllo descritte in precedenza. Il controllo PageViewer usa i controlli PageSource e PageElement per fornire la funzionalità di impaginazione. Il controllo PageSource interrompe e formatta il contenuto tra le pagine. Il controllo PageElement esegue il rendering di una singola pagina. Il controllo PageViewer usa anche il controllo PageBar per consentire di spostarsi tra le pagine.
L'uso del controllo PageViewer è molto semplice. Per visualizzare un documento noto, è possibile usarlo come illustrato nel codice seguente. Naturalmente, è possibile collegare gestori eventi e modificare il documento di origine per causare la visualizzazione di documenti diversi dal visualizzatore di pagine.
<Border
xmlns="https://schemas.microsoft.com/2003/xaml"
xmlns:def="Definition"
Background="BlanchedAlmond"
>
<PageViewer Source="AuthorsandPublishers.xaml" />
</Border>
La figura 3-17 mostra il visualizzatore di pagine ospitato in una finestra del browser che visualizza il relativo documento. Prendere nota dei controlli di spostamento della pagina nella parte superiore del documento.
Figura 3-17. Controllo PageViewer
Servizi layout documenti
Longhorn offre anche servizi di layout dei documenti progettati per migliorare l'esperienza di lettura. Longhorn contiene il supporto per due nuovi tipi di documenti:
- Documenti del flusso adattivo
- Documenti di layout fissi
Questi nuovi formati di documento consentono agli sviluppatori di offrire agli utenti delle applicazioni un'esperienza di lettura dei documenti migliore.
I documenti del flusso adattivo usano elementi di markup specializzati che dichiarano che un documento deve essere adattivo. Longhorn ottimizza automaticamente un documento adattivo per usare al meglio lo spazio disponibile sullo schermo e offre la migliore esperienza di lettura per l'utente in base alle funzionalità o alle limitazioni del sistema.
Ad esempio, l'utente potrebbe avere uno degli schermi wide a 16 by-9 introdotti di recente. È molto difficile leggere una riga di testo che si estende su una linea orizzontale lunga. A seconda della larghezza della finestra, un documento adattivo può dividere il testo in due, tre o più colonne, riducendo così lo sforzo per l'analisi di una riga di testo da parte di un utente.
In un altro esempio, un documento può contenere un'immagine e un testo che scorre intorno all'immagine. Man mano che si riducono le dimensioni della finestra del documento in un documento non indipendente, l'immagine rimane a dimensione fissa e viene visualizzato meno del testo. Un documento adattivo potrebbe ridurre l'immagine quando determina che il testo insufficienti è visibile nella finestra. Questo consente al lettore di avere ancora un'idea generale di ciò che l'immagine ritrae, ma continuare a leggere il testo nel contesto dell'immagine. In una finestra più piccola, è probabile che ogni pixel di un'immagine sia meno importante e utile per il lettore che non sia in grado di leggere altro testo. Un'alternativa, ad esempio la separazione dell'immagine e il testo circostante in pagine separate, sconfigge l'intento dell'autore del documento, che doveva presentare il testo e l'immagine insieme nel contesto.
I documenti di layout fissi vengono visualizzati ogni volta, indipendentemente dalle dimensioni dello schermo del visualizzatore, dalle dimensioni della finestra o dal dispositivo di output. Si crea un documento di layout fisso usando elementi di markup specializzati o stampando un documento usando un driver della stampante WVG (Microsoft Windows Vector Graphics).
Documenti di layout adattivo
In un documento di layout adattivo si specificano le preferenze chiave nel markup a livello radice. Longhorn può quindi eseguire il rendering del documento in modo da sfruttare al meglio l'area della finestra e migliora la leggibilità. Longhorn determina automaticamente la larghezza ottimale e il numero di colonne per una pagina, le dimensioni ideali per tutti gli elementi di testo, le dimensioni e le posizioni ottimali per tutte le figure e la larghezza dei margini e dei grondaie per offrire la migliore presentazione complessiva del contenuto.
Creazione di un documento di layout adattivo
Per creare un documento di layout adattivo, usare markup dichiarativo simile al seguente:
<Border
xmlns="https://schemas.microsoft.com/2003/xaml"
xmlns:def="Definition"
Background="BlanchedAlmond"
>
<AdaptiveMetricsContext ColumnPreference="Medium"
FontFamily="Arial">
<TextPanel Background="white">
<Section>
<Heading OutlineLevel="1">Adaptive Layout Example</Heading>
<Paragraph>
This example shows the advanced capabilities of Adaptive Flow
Layout. Lorem ipsum dolor sit amet, consectetuer adipiscing
elit, sed diam nonummy nibh euismod tin cidunt ut laoreet dolore
magna aliquam erat volutpat. Ut wisi enim ad minim veni am, quis
nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip
ex ea commodo consequat. Duis autem vel eum iriure.</Paragraph>
<Paragraph>
<Image TextPanel.FlowBehavior="Figure" Source="picture1.jpg"
TextPanel.Emphasis="Medium" />
Notice how images and text are flowed intelligently to enhance the
reading experi ence. Lorem ipsum dolor sit amet, consectetuer
adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi e nim ad minim veniam,
quis nostrud exerci tation ullamcorper suscipit lobortis ni sl ut
aliquip ex ea commodo consequat. Duis autem vel eum iriure.
</Paragraph>
<Paragraph>Adaptive layout is an exciting new feature of Longhorn.
<Image TextPanel.FlowBehavior="Figure" Source="picture2.jpg"
TextPanel.Emphasis="Low" />
Lorem ipsum dolor sit amet, consectetuer
adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi e nim ad minim veniam,
quis nostrud exerci tation ullamcorper suscipit lobortis ni sl ut
aliquip ex ea commodo consequat. Duis autem vel eum iriure.
</Paragraph>
</Section>
</TextPanel>
</AdaptiveMetricsContext>
</Border>
documenti Fixed-Layout
Si usa un documento a layout fisso per presentare il contenuto del documento esattamente nello stesso layout e formato, indipendentemente dal software dell'applicazione, dall'hardware e dal sistema operativo usato. Inoltre, il rendering di un documento a layout fisso viene eseguito in modo identico in tutti i dispositivi di output. Un documento di layout fisso è un set di oggetti che descrivono collettivamente l'aspetto di una o più pagine.
Creazione di un documento Fixed-Layout
È possibile usare due tecniche diverse per produrre un documento a layout fisso:
- Stampare un documento senza markup in un file utilizzando il driver della stampante Longhorn
- Scrivere un documento a layout fisso usando XAML
Quando si stampa un documento utilizzando la maggior parte delle applicazioni Win32 di Microsoft (ad esempio, Microsoft Office) usando il driver della stampante Longhorn, il driver della stampante creerà un file XAML che contiene markup per impaginare e posizionare ogni carattere, immagine o elemento grafico vettoriale nel documento stampato.
È possibile scegliere di restituire il documento come file di markup direttamente o di includere il file di markup all'interno di un contenitore. Quando si seleziona l'output del contenitore, è anche possibile applicare diritti digitali e protezione dei documenti al documento.
In alternativa, puoi creare XAML usando un editor. Di seguito è riportato un esempio di documento a layout fisso:
<FixedPanel xmlns="https://schemas.microsoft.com/2003/xaml/" >
<FixedPage Width="8.50in" Height="11.00in"> <!-- PAGE 1 -->
<Text FontFamily="Arial" FontSize="8.4" FixedPage.Left="1.250in"
FixedPage.Top="0.530in" FontWeight="Bold">1.</Text>
<Text FontFamily="Arial" FixedPage.Left="1.350in" FixedPage.Top="0.500in"
FontWeight="Bold" FontSize="12">Fixed Document</Text>
</FixedPage>
<FixedPage>
<Text>This is page 2</Text>
</FixedPage>
<FixedPage>
<Text>This is page 3</Text>
</FixedPage>
</FixedPanel>
Riepilogo
I pannelli consentono di dividere la superficie di visualizzazione in aree con caratteristiche di layout diverse. È disponibile un'ampia gamma di controlli che è possibile usare per popolare i pannelli di uno schermo. Forme, trasformazioni e animazioni consentono di produrre output grafico dinamico. Utilizzando la composizione dei controlli, è possibile combinare queste funzionalità per produrre praticamente qualsiasi interfaccia utente desiderata. È possibile produrre documenti adattivi per disporre il contenuto in modo intelligente e semplificare la lettura da parte del lettore. In alternativa, è possibile posizionare con precisione ogni singolo elemento in una pagina e controllare la paginazione in modo esplicito per produrre un documento che appare esattamente come si desidera indipendentemente dal dispositivo di output. Inoltre, puoi farlo in modo dichiarativo usando XAML. Questo è sicuro che quando cazzo batte la scrittura di un gestore di messaggi WM_PAINT!