Confessions of a .NET Developer!

FlowDocuments in WPF – Part 2

In this post I will be discussing Tables, BlockUIContainers and Floaters.

First lets discuss Tables. As the name suggests, you can display the data in a tabular format. Here is how it will look like :

Tables

Tables

Here is the XAML :

        <FlowDocumentReader Margin="12" Name="flowDocumentReader1">
            <FlowDocument>
                <Paragraph>Time to create a Table</Paragraph>
                <Table>
                    <Table.Columns>
                        <TableColumn Width="100"/>
                        <TableColumn Width="120"/>
                    </Table.Columns>
                    <TableRowGroup>
                        <TableRow FontSize="18" FontWeight="Bold">
                            <TableCell Background="Beige">
                                <Paragraph>Name</Paragraph>
                            </TableCell> 
                            <TableCell Background="Beige">
                                <Paragraph>Company</Paragraph>
                            </TableCell>
                        </TableRow>
                        <TableRow>
                            <TableCell>
                                <Paragraph>Gagan</Paragraph>                                
                            </TableCell>
                            <TableCell>
                                <Paragraph>BirlaSoft</Paragraph>
                            </TableCell>
                        </TableRow>
                        <TableRow>
                            <TableCell>
                                <Paragraph>Sachin</Paragraph>
                            </TableCell>
                            <TableCell>
                                <Paragraph>Steria</Paragraph>
                            </TableCell>
                        </TableRow>
                        <TableRow>
                            <TableCell>
                                <Paragraph>S.A.Kryukov</Paragraph>
                            </TableCell>
                            <TableCell>
                                <Paragraph>Milara Inc</Paragraph>
                            </TableCell>
                        </TableRow>
                        <TableRow>
                            <TableCell>
                                <Paragraph>Pulkit</Paragraph>
                            </TableCell>
                            <TableCell>
                                <Paragraph>Infosys</Paragraph>
                            </TableCell>
                        </TableRow>
                    </TableRowGroup>
                </Table>

Simple isn’t it! To define columns, use Table.Columns and define each column using TableColumn. For the row, its a bit different. Add TableRowGroup which consists of a group of TableRow’s(one for each row) which in turn contains TableCell’s(one for each column). You can do formatting to your columns by providing background colors, font size etc. Cool.

I have discussed Hyperlink in the previous post. Lets move on to BlockUIContainer.
This is one of the important features in FlowDocuments. With BlockUIContainer, you can add “non-content” elements into your FlowDocument such as Buttons, ListBox also including Layout containers like Grid and StackPanel. The only thing is that only a “single” element can be placed in it, though multiple elements can be placed in the StackPanel.
Its easy to use, here is the simple XAML :

                <BlockUIContainer>
                    <Button Height="30"
                            Width="90"
                            Content="Click Me!"
                            Name="btnBrowse"
                            Click="btnBrowse_Click"/>                            
                </BlockUIContainer>

A simple button has been inserted, you can handle the click event in the code-behind of your application.

Next up Floaters! As the name suggests, the contents of your document can “float” in your FlowDocument.
Here is what I meant :

Floaters

Floaters

And here is the XAML :

                <Paragraph>
                    WPF is a completely new presentation framework, integrating
                    the capabilities of many frameworks that have come before
                    it,
                    <Floater HorizontalAlignment="Left"
                             Width="60">
                        <BlockUIContainer>
                            <Image Source="Bear.bmp"/>    
                        </BlockUIContainer>
                    </Floater>
                    including User, GDI, GDI+, and HTML as well as being heavily
                    influenced by toolkits targeted at the Web.
                </Paragraph>

Add the Image “Bear.bmp” or any other picture as a resource in your project for easy access! Image has to be wrapped in a BlockUIContainer.

Do note the way I have placed the Image as a Floater. After the word it, the floater will be placed on the left side of the FlowDocument, and then the following sentence gets added. If you want the Image to be placed at the right, just change the HorizontalAlignment to Right.

That’s it! In the next part, I might bring adding FlowDocument programmatically. Credit goes to this book : Apress Pro WPF by Matthew MacDonald from which I learned.

Thanks for reading! Happy coding! 🙂

Advertisements

April 27, 2011 Posted by | WPF | 2 Comments

FlowDocuments in WPF Part 1

WPF brings out FlowDocument for readability purpose which has numerous in-built features for easing viewing of text. It actually consists of a number of blocks and resembles with HTML.
For more reading head to this link :

The MSDN says there are four types of controls:
– RichTextBox
– FlowDocumentReader
– FlowDocumentScrollViewer
– FlowDocumentPageViewer

Here I will be using FlowDocumentReader because the 3rd and 4th controls are in-built in it specified as “modes” of viewing.

Lets get started now. First of all, add the FlowDocumentReader component in your toolbox. Like below :

1) Right click on Controls header from the ToolBox and select Choose Items.

ChooseItems

ChooseItems

2) A window will open, select “WPF Component”, check the controls and click Ok.

WPF Components

WPF Components

There now we can start.
Check out this window :

SimpleWindow

SimpleWindow


That’s how a flow document will look like.

Lets try the “FlowDocumentPageViewer” mode by clicking the second control to left of the zoom control.

PageMode

PageMode

And in the Scrolling mode.

ScrollMode

ScrollMode

This is how the self-explanatory object structure of a FlowDocument looks like(taken from MSDN):

Object Model

Object Model

Here is the XAML code to create the first page of the above window :

    <Grid>
        <FlowDocumentReader Margin="12,12,12,0" Name="flowDocumentReader1">
            <FlowDocument>
                <Paragraph>
                    <Italic FontWeight="Bold">FirstParagraph</Italic>
                </Paragraph>
                <Paragraph FontFamily="Verdana"
                           FontSize="14">
                    <Run>A flow document is designed to "reflow content" depending 
                         on window size, device resolution, and other 
                         environment variables.
                    </Run>           
                </Paragraph>
                <Paragraph>
                    <Run>
                        Flow documents have a number of built in features including 
                        search, viewing modes that optimize readability, 
                        and the ability to change the size and appearance of fonts.                    </Run>
                    <Hyperlink Click="Hyperlink_Click">Now this is a hyperlink</Hyperlink>
                </Paragraph>
              </FlowDocument>
             </FlowDocumentReader>
       </Grid>

As you see, the document consists of paragraphs, where you can set the Font properties, background etc. The “Run” element is used specifically for Text only.
I have also added a Hyperlink, you can handle the click event in your code-behind, such as opening a Firefox browser etc.
You can search text which is its in-built feature together with zooming.

We can also create a List of items which look like Bullets.
Here is a window that displays it :

List

List

Here is its XAML :

                <List>
                    <ListItem>
                        <Paragraph>Tarun</Paragraph>
                    </ListItem>
                    <ListItem>
                        <Paragraph>Kumar</Paragraph>
                    </ListItem>
                    <ListItem>
                        <Paragraph>Singh</Paragraph>
                    </ListItem>
                </List>
                
                <Paragraph>A numbered List</Paragraph>
                <List MarkerStyle="Decimal">
                    <ListItem>
                        <Paragraph>WPF is awesome!</Paragraph>       
                    </ListItem>
                    <ListItem>
                        <Paragraph>Indeed it is</Paragraph>
                    </ListItem>
                </List>

Set the Marker style to get different ways of specifying the bullets and numbers.
See how neatly it has presented it.

That’s it for the first part. Next part will be about Tables and Floaters. Stay tuned! 🙂

April 25, 2011 Posted by | WPF | 1 Comment

Read Huge XML files faster

Most developers use the XmlDocument class to read XML files. LINQ has given us an excellent class XDocument which is much better than XmlDocument, inserting and deleting has become easy with XDocument. But both these classes are inefficient in handling huge XML files which are for example 500MB or 2-3 GB.

The problem is that once you load the XML using these classes, they store the whole XML in memory which eventually creates memory overheads. If you load these huge files into the memory then you might get an exception like this :
“System out of memory exception”.

So the solution for this will be to use XmlTextWriter and XmlTextReader class which is a stream-based XML reader rather than an in-memory XML reader.
These two classes read the XML node by node instead of loading the whole document. Its very much similar to using StreamWriter or StreamReader!

Lets take an example of creating an xml file from scratch.

        Dim filePath As String = "C:\Users\Tarun\Desktop\Prac.xml"
        Dim fs As FileStream = New FileStream(filePath, FileMode.Create, FileAccess.Write)
        Dim xtw As XmlTextWriter = New XmlTextWriter(fs, Text.Encoding.UTF8)

        xtw.Formatting = Formatting.Indented  ' Used so that it can be easily read while opening in Notepad
        xtw.Indentation = 4

        xtw.WriteStartDocument(True)
        xtw.WriteStartElement("Products")
        xtw.WriteComment("This is a comment")

        xtw.WriteStartElement("Product")
        xtw.WriteAttributeString("ID", "1")
        xtw.WriteAttributeString("Name", "Sony")

        xtw.WriteStartElement("Price")
        xtw.WriteString("40.33$")
        xtw.WriteEndElement()  'Closes the Price element
        xtw.WriteEndElement()  'Closes the Product element

        xtw.WriteStartElement("Product")
        xtw.WriteAttributeString("ID", "2")
        xtw.WriteAttributeString("Name", "Dell")

        xtw.WriteStartElement("Price")
        xtw.WriteString("80$")
        xtw.WriteEndElement()  'Closes the Price element
        xtw.WriteEndElement()  'Closes the Product element

        xtw.WriteEndElement()  'Closes the Products element
        'xtw.WriteEndDocument()
        xtw.Close()  'Close the XmlTextWriter stream
        fs.Close()  'Close the FileStream

The functions used are self-explanatory. But writing an XML file was not our purpose. Now lets read this XML.

        Using fs As FileStream = New FileStream(filePath, FileMode.Open, FileAccess.Read)

            Dim xtr As XmlTextReader = New XmlTextReader(fs)
            Dim writer As StringWriter = New StringWriter()
            'Read each and every node encountered
            While (xtr.Read())
                writer.Write("Type:")
                writer.Write(xtr.NodeType.ToString())

                If (xtr.Name <> "") Then
                    writer.Write("Name:")
                    writer.Write(xtr.Name)
                End If

                If (xtr.Value <> "") Then
                    writer.Write("Value:")
                    writer.Write(xtr.Value)
                End If

                If (xtr.AttributeCount > 0) Then
                    writer.Write("Attributes")
                    For i As Integer = 0 To xtr.AttributeCount - 1
                        writer.Write(" ")
                        writer.Write(xtr.GetAttribute(i))
                        writer.Write(" ")
                    Next
                End If

            End While

            Dim s As String = writer.ToString()
            Dim strm as StreamWriter = new StreamWriter("C:\HereisTheResult.txt",false);
            strm.Write(s); //Write the result to the txt file.

        End Using

April 8, 2011 Posted by | XML | Leave a comment