Confessions of a .NET Developer!

WPF Tutorial : Drawing Visual

As described in the MSDN, is a lightweight drawing class to render shapes, images, videos, text etc. It’s so lightweight that it needs a container to hold it, also the fact that it doesn’t provide layout or hit-testing or event-handling.

So for holding our DrawingVisual, we will use a which will provide layout, hit-testing and event-handling.

Lets get started by creating a class DrawIt which inherits FrameworkElement class. In this class we will create two rectangles using DrawingVisual class.

    class DrawIt:FrameworkElement
    {
        VisualCollection visuals;

        public DrawIt()
        {
            visuals = new VisualCollection(this);

            this.Loaded += new RoutedEventHandler(DrawIt_Loaded);
        }

        void DrawIt_Loaded(object sender, RoutedEventArgs e)
        {
            int x = 0;
            
            for (int i = 0; i <= 1; i++)
            {
                DrawingVisual visual = new DrawingVisual();
                using (DrawingContext dc = visual.RenderOpen())
                {
                    dc.DrawRectangle(Brushes.Red, new Pen(Brushes.Black, 2),
                        new Rect(new Point(0 + x, 0), new Size(40, 40)));
                }
                visuals.Add(visual);
                x += 60;
            }
        }

        protected override Visual GetVisualChild(int index)
        {
            return visuals[index];
        }

        protected override int VisualChildrenCount
        {
            get
            {
                return visuals.Count;
            }
        }
    }

Explanation :

For this class, we have defined visuals of type VisualCollection. VisualCollection will keep the number of visual objects that we have drawn so far.
In the LoadedEvent, I am running a for-loop to draw 2 rectangles. In that, a DrawingVisual object is created for every loop made. The RenderOpen() method of DrawingVisual will return an object of type DrawingContext which is used to render the content of the visual. This line is straight from MSDN: “When you use a DrawingContext object’s draw commands, you are actually storing a set of rendering instructions that will later be used by the graphics system; you are not drawing to the screen in real-time”. This will greatly improve the performance.
Then there are two overrides which will be used by our container to manage the collection of the visual objects.

Next is to display our visuals in a Window. Here is the XAML of our window.

<Window x:Class="LearnDrawing.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:LearnDrawing"
    Title="Window1" Height="300" Width="300">
    <Grid>
        <local:DrawIt Width="100" Height="100"/>
    </Grid>
</Window>

And the window will display this:

Window

Window

I would like you to read these articles too which helped me a lot:

http://jerryclin.wordpress.com/2007/11/21/lightweight-drawing-with-drawingvisuals-part-1-of-2
http://jerryclin.wordpress.com/2007/12/19/lightweight-drawing-with-drawingvisuals-part-2-of-2
http://msdn.microsoft.com/en-us/library/ms748373%28v=VS.90%29.aspx

That’s it. Hope it helped you. Happy coding!

May 19, 2011 Posted by | WPF | 1 Comment

Basic Linq to XML operations

This post shall deal with Inserting, Deleting and Modifying XML data using Linq to XML.

Here is how the XML will look like:

<?xml version="1.0" encoding="utf-8" ?>
<access>
  <user id="149">
    <name>Tarun</name>
    <age>22</age>
    <company>ABC</company>
  </user>
  <user id="13">
    <name>Gagan</name>
    <age>23</age>
    <company>Birla</company>
  </user>
  <user id="45">
    <name>Sachin</name>
    <age>24</age>
    <company>Steria</company>
  </user>
</access>

Add this XML to your project or create one using the XML Editor and set its Build Action to “Content” instead of Resource and also set Copy to Output Directory to “Copy if Newer”. With its build action set to content, I can modify the XML.

The code to Load the XML using the XDocument class under the namespace System.Xml.Linq

XDocument xDoc = XDocument.Load("XMLAccess.xml");
XElement rootElem = xDoc.Root;

And here is the way to Insert a new Record(User) into the XML :

            rootElem.Add(new XElement("user",
                new XAttribute("id", 90),
                new XElement("name", "Pulkit"),
                new XElement("age", 19),
                new XElement("company", "Infosys")));

            xDoc.Save("XMLAccess.xml");

Its quite simple using Linq, and a lot messier in case of the standard XmlDocument class.

The code to delete a User:

            XElement delElem = (from XElement elem in xDoc.Descendants("user")
                                where int.Parse(elem.Attribute("id").Value) == 90
                                select elem).Single<XElement>();

            delElem.Remove();
            xDoc.Save("XMLAccess.xml");

So the above Linq expression will return a single XElement of type user of id=90 and gets removed using a simple Remove() function.

And the code to update the XML :

            XElement updElem = (from XElement elem in xDoc.Descendants("age")
                                where int.Parse(elem.Parent.Attribute("id").Value)==45
                                select elem).Single<XElement>();

            updElem.SetValue(48);
            xDoc.Save("XMLAccess.xml");

That’s it for now. Happy coding.

May 4, 2011 Posted by | LINQ, XML | Leave a comment

FlowDocuments in WPF – Part 3

In this small post, I shall explain how to save and load the flow documents that you have created. For this, there are two classes, XamlWriter and XamlReader.
You can read more about XamlReader and XamlWriter here :
and respectively.

Create two buttons(btnSave to Save and btnOpen to Open a flowdocument) and add a FlowDocumentReader to your WPF application.

In the save button, use FileStream to create a .xaml file and save the document there.

        private void btnSave_Click(object sender, RoutedEventArgs e)
        {
            using (FileStream fs = File.Open(@"C:\Save.xaml", FileMode.Create))
            {
                XamlWriter.Save(flowDocumentReader1.Document, fs);
            }
        }

Load the document from a location :

            using (FileStream fs = File.OpenRead(@"C:\Open.xaml"))
            {
                FlowDocument document = (FlowDocument)XamlReader.Load(fs);
                flowDocumentReader1.Document = document;
            }

Thats it, nothing much complicated here. Good luck!

May 1, 2011 Posted by | WPF | Leave a comment