Gianni Giaccaglini

Tricks & mini applics on WPF
posts - 46, comments - 0, trackbacks - 0

FlowDocumentReader, servizievole lettore di FlowDocument

  

Fino a ieri chi programma applicativi invidiava in cuor suo la semplicità offerta dal “linguaggio” (dichiarativo) HTML e derivati per creare pagine Web davvero ricche. Ah poter lavorare con altrettanta facilità da codice VB, C# e compagnia cantante! WPF e Silverlight consentono di farlo in vari modi, il più diretto e comodo è il potente oggetto FlowDocument , sostanzialmente in virtù dell’adozione della sua anima, appunto, dichiarativa: l’XAML.

Piccola digressione. Ma l’XML, di cui XAML è figlio, non è nato in origine per separare dati e formati? Vero, ma presto ci si è resi conto che la sua flessibilità permette schemi di qualsiasi tipo, invadendo così anche scopi formattanti. Si pensi al formato Open XML di Office 2008 e 2010, che comprende componenti dedicati ai formati di celle Excel, paragrafi, parole di Word. (Che poi ne derivi una certa confusione è un’altra, anzi è la solita storia Informatica…).

 La classe FlowDocument è relativa a un oggetto potente, un vero e proprio documento di testo che si articola in oggetti-figli genericamente catalogati come Block (v. Guida), ma che in pratica hanno nomi eloquenti. Il più importante è Paragraph – uno o generalmente più d’uno -, cui corrisponde in XAML una coppia di tag omonime entro la quale si può inserire un brano di testo. A sua volta un sub-testo può essere  racchiuso fra <Bold>...</Bold> o <Italic>...</Italic> ecc., a denotare e far apparire a video grassetti, corsivi e quant’altro. Ancor più bella è la possibilità di includere altri oggetti d’ogni tipo, come forme, immagini  nonché controlli.

In questo piccolo tutorial entro in medias res con un esempio semplice ma tipico. Prima è necessaria una premessa:

Un FlowDocument deve essere racchiuso in un contenitore. Il più potente e comodo dei quali è lo specifico FlowDocumentReader. In pratica in XAML si avrà una situazione come la seguente:

Figura 1

 

Quest’altra figura illustra una situazione dopo varie manovre tramite il lettore e allargamento della finestra fino a visualizzare l’intero documento.

 Figura 2

  

Si osservi l’adeguamento automatico della larghezza dei paragrafi nonché la presenza di un grassetto, un corsivo, tre pulsanti di opzione, una lista con quattro elementi , due dei quali corredati di shape, e un pulsante di comando. La figura precedente mostra quel che accade cliccando su di esso.

Per non deludere Impazienti & Curiosi ecco la banale routine responsabile, associata all’evento Click di tale Button, denominato per eccesso d’immaginazione, puls1:

Sub Raddoppia()

    Dim pulsH = puls1.Height

    Dim pulsW = puls1.Width

    puls1.Height *= 2 : puls1.Width *= 2

    MessageBox.Show("Ora ripristino le dimensioni del pulsante")

    puls1.Height = pulsH

    puls1.Width = pulsW

End Sub

Tutto il codice XAML

Dopo quanto detto ritengo quasi del tutto sufficiente riportare la parte dichiarativa del programmino, affidandomi all’eloquenza delle varie tag. Aggiungo solo che per prendere due piccioni ho utilizzato anche un controllo Expander, a monte del FlowDocumentReader. In tal modo il nostro documento può essere collassato (e occultato) o espanso per una sua più o meno ampia visualizzazione.

<Window x:Class="MainWindow"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    Title="FlowDocumentReader" Height="450" Width="525">

    <Grid>

        <Grid.RowDefinitions>

            <RowDefinition Height="250*" />

            <RowDefinition Height="61*" />

        </Grid.RowDefinitions>

        <Expander Header="Espandi il documento" Name="Expander1" Margin="0,0,0,39">

            <FlowDocumentReader Margin="9,0,-9,0" Height="244">

                <FlowDocument FontSize="12" xml:space="preserve">

                <Paragraph TextAlignment="Center" FontSize="22">

                <Bold>Lettore di documenti</Bold></Paragraph>

                <Paragraph>

Un FlowDocumentReader permette di inserire testi qualsiasi, variamente <Italic>formattati</Italic>, dopo di che tale contenuto, <Bold>FlowDocument</Bold>, viene visualizzato nello spazio disponibile - in modo simile a quello di una pagina HTML.

                </Paragraph>

                <Paragraph>Inoltre si può inserire un pulsante come quello seguente:

                <Button Name="puls1" Height="40" Width="100" Click="Raddoppia">Clicca e stupisci</Button> Il clic raddoppia/ripristina le dimensioni del Button. Grazioso, vero?             

                 Scegli una di queste opzioni:                  

                 <StackPanel>

                    <RadioButton IsChecked="True">Si</RadioButton>

                    <RadioButton>No</RadioButton>

                    <RadioButton>Non so</RadioButton>

                </StackPanel>

               </Paragraph>

                <Paragraph><Bold>Si possono anche avere delle liste:</Bold></Paragraph>

                <List>

                <ListItem><Paragraph>Primo elemento</Paragraph></ListItem>

                <ListItem><Paragraph>Secondo elemento</Paragraph></ListItem>

                <ListItem><Paragraph>Terzo elemento: un cerchio! <Ellipse Fill="Red"

                Width="20" Height="20"></Ellipse></Paragraph></ListItem>

                <ListItem><Paragraph>Quarto elemento: quadrato! <Rectangle

                Fill="Blue" Width="20" Height="20"></Rectangle>

                </Paragraph></ListItem>

                </List>

                </FlowDocument> 

            </FlowDocumentReader>

     </Expander>

        <Button Grid.Row="1" Height="20" Name="PulsPrimario" Click="ProvaBis" Content="Espandi..." Margin="0,28,0,12" />

</Grid>

</Window>

NOTA - Il precedente listato potrebbe non dare risultato del tutto fedele rispetto alle figure precedenti in quanto qui riprodotto a mano. L'opzione xml:space="preserve" serve a mantenere gli spazi rispetto allo standard XML, ma non garantisco che tutto sia OK col codice testé riportato...

Altre quisquilie a proposito di Expander

Con l’occasione fornisco due semplici routine relative ai due opposti eventi  dell’Expander, cui nel predetto XAML è stato affibbiato il banal nome Expander1:

Private Sub Expander1_Expanded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Expander1.Expanded 

        Expander1.Header = "Comprimi"      

End Sub

  

Private Sub Expander1_Collapsed(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Expander1.Collapsed

        Expander1.Header = "Espandi il documento"

End Sub 

Hanno lo scopo di modificare opportunamente l’intestazione (Header).

A proposito di Expander, espongo infine una perplessità e una richiesta, temo, utopistica. La prima è la constatazione, salvo segreti che ignoro, che l’Expander non si può applicare a singoli paragrafi, a meno di non suddividere un documento e applicare un FlowDocumentReader a ciascuno spezzone (il che non mi pare bello). La richiesta sarebbe la possibilità (esposta da vari siti di quotidiani ecc.) di esibire solo la parte iniziale di un articolo espandibile. Si può fare lo stesso con WPF? E come?

Print | posted on giovedì 3 febbraio 2011 17:14 |

Feedback

No comments posted yet.

Post Comment

Title  
Name  
Email
Url
Comment   
Please add 2 and 2 and type the answer here:

Powered by:
Powered By Subtext Powered By ASP.NET