Posts tagged ‘C#’

July 14th, 2010

Using HtmlAgilityPack to parse a website.

Bing.com Twitter Bird Image ResultsIn my line of work I’m often asked to come up with some unique data sources to power some of our information visualizations. Often times this data  is not available in an API or RSS feed. Sometimes it’s just available in HTML. Up until recently I’ve shied away from parsing HTML with RegEx or XML parsers because they can be really processor intensive and give mixed results.

This past week I had another need for some data in an HTML page as a data source, this time for a WPF application. Since I needed to make it work I did a quick search on on the internet for some HTML parsers. What I found was amazingly useful. The HtmlAgilityPack is a .NET library that gives all the tools to parse your HTML, retrieve the data you’re looking for. It supports Linq to Objects and has XPATH implementation to let you find what you need easily. PLUS, because it’s on codeplex it’s open-source and free! Fantastic!

Here is a little code snippet if you ever wanted to know how many Twitter Bird image results are in a Bing.com search. Note that I’m using the XPATH syntax to find the <span> tag with and ID value of ‘sw_ptc’ and then select the InnerText from that node. HtmlAgilityPack has lots of XPATH and XSLT options so you’ll be able to find whatever your looking for with minimal effort.

using System;
using System.IO;
using System.Net;
using System.Configuration;
using System.Xml.Linq;
using HtmlAgilityPack;
class BingCounter
    {
        private WebClient webClient;
        public BingCounter()
        {
            Uri _feedUri = new Uri("http://www.bing.com/images/search?q=twitter+bird");
            webClient = new WebClient();
            webClient.DownloadDataCompleted += new DownloadDataCompletedEventHandler(stringDataCompletedEvent);
            webClient.DownloadDataAsync(_feedUri);
        }
        private void stringDataCompletedEvent(object sender, DownloadDataCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                try
                {
                    byte[] xmlString = e.Result;
                    HtmlDocument doc = new HtmlDocument();
                    doc.Load(new StreamReader(new MemoryStream(xmlString)));
                    string results = "";
                    foreach (HtmlNode span in doc.DocumentNode.SelectNodes("//span[@id='sw_ptc']"))
                    {
                        results = span.InnerText;
                    }
                }
                catch (Exception exp)
                {
                    Console.Write(exp.Data);

                }
            }
        }

Have fun and happy coding.

September 14th, 2009

Getting and using the pixels of your Visual in WPF

Have you ever wanted to get the Bitmap Data (pixels) of a Visual (Canvas, Grid, etc) in WPF or Silverlight from memory and without having to add it to the root visual. After doing a lot of trial and error here is a quick piece of code and a sample project that can help you accomplish exactly that.

There are plenty of cool ways to extend this project including some cool transition and other code based animations. Just let your imagination go wild!

First, create a new WPF Application in Visual Studio or [download a sample project]. In your Window1.xaml give the Grid an x:Name value. You’ll use this to add your elements later on.

<br  /><grid x:Name="VisualRoot"></grid><br />

Now lets add a new Page to our project. We’re going to alter the Page to extend a Canvas rather than a Page for no other reason then when I’m creating animations I prefer to work with a Canvas. We are going to put some visuals onto our canvas. In the sample it’s a blue square with a red circle next to it and a little bit of text below it. It could be any UIElement including another Canvas/Grid, Images, Text anything.

In our Window1.xaml code behind we’re going to create an instance of our Canvas1 and call the methods to have WPF Measure, Arrange, and UpdateLayout in memory. We need to call these methods in order for WPF to figure out where all the pixels are positioned in our visual to return accurate Bitmap Data. These methods are called automatically when you add a Visual to WPF using the Visual.Children.Add() method.

The CreateBitmapSourceFromVisual function was taken from a project on CodePlex, unfortunately I can’t recall the link. I’ll add it here if I run across it again. That function takes a Visual and returns a BitmapSource object with the pixel data. It automatically updates the dots per inch (DPI) to 96, which is required for WPF to render properly).

Here is the code behind from our root Window.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace BitmapFromVisualSample
{
    /// 
    /// Interaction logic for Window1.xaml
    /// 
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
            Canvas1 myVisualElement = new Canvas1();
            myVisualElement.Measure(new System.Windows.Size(0, 0));
            myVisualElement.Arrange(new Rect(new System.Windows.Size(0, 0)));
            myVisualElement.UpdateLayout();
            // Note the myVisualElement is never added

            // Use myVisualElement to get our Bitmap Source Data.
            BitmapSource myVisualElementBitmapData = CreateBitmapSourceFromVisual(300, 500, myVisualElement, false);
            // Create an Image for your Bitmap Source
            Image myImage = new Image();
            // use our Bitmap Data 
            myImage.Source = myVisualElementBitmapData;

            // Add our Image to the Grid
            VisualRoot.Children.Add(myImage);
        }
        public BitmapSource CreateBitmapSourceFromVisual(Double width, Double height, Visual visualToRender, Boolean undoTransformation)
        {
            if (visualToRender == null)
            {
                return null;
            }
            RenderTargetBitmap bmp = new RenderTargetBitmap(
                                            (Int32)Math.Ceiling(width),
                                            (Int32)Math.Ceiling(height),
                                            96,
                                            96,
                                            PixelFormats.Pbgra32);
            if (undoTransformation)
            {
                DrawingVisual dv = new DrawingVisual();
                using (DrawingContext dc = dv.RenderOpen())
                {
                    VisualBrush vb = new VisualBrush(visualToRender);
                    System.Windows.Point myPoint = new System.Windows.Point();
                    dc.DrawRectangle(vb, null, new Rect(myPoint, new System.Windows.Size(width, height)));
                }
                bmp.Render(dv);
            }
            else
            {
                bmp.Render(visualToRender);
            }
            return bmp;
           
        }
    }
}

You can run the sample project and you will see the visual we created in Canvas1. We used the BitmapSource object of the Canvas1 as the Source of our Image. Note: we never added Canvas1 to the root visual, we simply created it in the code behind and retrieved the pixel data from that visual to use as on our Image. I leave it to you to play with this technology to create cool WPF/Silverlight animations.

[Download Source Code] as Visual Studio Project.

December 1st, 2008

Building Custom Events in C#

The more I learn Object Oriented Programing techniques the more I value the ability to have my classes listen to each other. I’ve been working in C# a lot recently for a WPF project. At various points throughout the development process I’ve found a need to have different events cause effects among objects and classes. .NET has a great list of events built into many of their classes especially the UIElements and Controls. What I want to do is put together some code snippets on how to build a custom event for your object and hopefully to help some new C# programmers better understand how events work and how powerful they can be.

What in the world does that do you ask…well lets break it down.

The first part of this example is based on a WPF Application template from Visual Studio 2008. It includes all the using statements, the namespace deceleration and the Window1 class. The reason I included all this is so that you can download the Project file and poke around.

Inside the Window1 constructor we’re going to create an instance of our EventBroadcasterClass so that we can use it to send out our custom event.

The EventBroadcasterClass has a public event myEvent and a Method to broadcast it, MyEventMethod. The constructor method then creates a new CustomEventHandler Object myEventHandler and adds it’s Handle method as a listener to the EventBroadcasterClass myEvent event.

You can pass a variety of data through events (although it’s not always the best approach). In this case we set up a new CustomEventArgs object and added some text to it. “Text from EventBroadcasterClass” will be used by our CustomEventHandler later on. Here is the whole EventBroadcasterClass.

The CustomEventHandler is very simple. It has a string property and a Handle method. As you can see the Handle method takes two arguments. object sender is where the event was broadcast from, in this case it’s the EventBroadcasterClass, and a CustomEventArgs object. This is where the string value we set in our broadcaster is held. To access it we just have to set our string property to the CustomEventArgs public property MyString. Then all we do is write it out to the Console for demonstration purposes. Here is the CustomEventHandler Class

The final piece of this puzzle is the CustomEventArgs. This Class just hold the arguments we pass between events and listeners. You can fill this object will anything, although it can really hurt performance if you pass too much data in event args. The constructor method sets a private property and the public MyString property which has a get to return the value set when the CustomEventArgs object is created. Directly below we see a public delegate CustomEvent. This delegate is used to relay your event to any object that is listening.

It took me some time to put all these pieces together, but now that I have I can build Classes that are always aware of what others are doing, which can have some very cool effects. I hope this little summary will help others get up to speed quickly building Custom Events in C#.

Download the Source Code

Tags: