How can I debug my GraphDataProvider?

Apr 29, 2011 at 1:59 PM

Hi,

I am developing a custom GraphDataProvider for NodeXL and followed the instructions given in the help file. Everything works fine and I can see my custom provider in the "Import" menu in Excel 2010. My question is: How can I debug my overridden TryGetGraphData method in VS? I added a debug event in VS which starts excel and opens the NodeXLGraph.xltx file. While that does work and the debugger is apparently attached to excel, my breakpoints in VS are not hit. If I stop the debugger, excel closes as expected.

Thanks in advance!

Apr 29, 2011 at 4:33 PM
Edited Apr 29, 2011 at 4:40 PM

Simon:

I wouldn't try debugging a GraphDataProvider that way, because it's too slow and tedious.  Instead, I would bypass Excel entirely during testing and create a simple Windows Forms test project, like so:

1. In your Visual Studio solution, add a Windows Forms project.  Call it TestGraphDataProvider.

2. In the TestGraphDataProvider project, add a reference to your MyGraphDataProvider project.

3. In TestGraphDataProvider's main form, add a button whose Click event handler calls MyGraphDataProvider.TryGetGraphData().

4. When TryGetGraphData() returns, add the returned graph data to a TextBox on your form.  Or if you want to be able to expand and collapse the graph data, which of course is XML, add the returned graph data to a WebBrowser control on your form.  The WebBrowser understands XML and shows plus and minus signs to allow XML nodes to be collapsed.

5. In Visual Studio, right-click the TestGraphDataProvider project in Solution Explorer and select "Set as Startup Project."

6. Press F5.  Visual Studio will start your test project, and you can easily set breakpoints and step into your MyGraphDataProvider project.

The test project is very quick and simple, and it allows you to verify that your GraphDataProvider works before plugging it into Excel.  Once you plug it into Excel, it should just work.  (If it doesn't, NodeXL should give you an error message telling you what's wrong with your XML.)

-- Tony

Apr 29, 2011 at 4:37 PM

In the next post, I'm including the source code for MainForm.cs in NodeXL's TestGraphDataProviders project, which is what I use to test the Twitter, Flickr and YouTube GraphDataProviders that I wrote.  (This source code, which you DO NOT need to build a custom GraphDataProvider, is available on NodeXL's Downloads tab on CodePlex.)

-- Tony

Apr 29, 2011 at 4:38 PM

//  Copyright (c) Microsoft Corporation.  All rights reserved.

using System;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using Microsoft.NodeXL.ExcelTemplatePlugIns;
using Microsoft.NodeXL.GraphDataProviders.Twitter;
using Microsoft.NodeXL.GraphDataProviders.Flickr;
using Microsoft.NodeXL.GraphDataProviders.YouTube;

namespace Microsoft.NodeXL.TestGraphDataProviders
{
/// <summary>
/// </summary>

public partial class MainForm : Form
{
    /// <summary>
    /// </summary>

    public MainForm()
    {
        InitializeComponent();
    }

    private void btnTwitterUser_Click(object sender, EventArgs e)
    {
        GetGraphData( new TwitterUserNetworkGraphDataProvider() );
    }

    private void btnTwitterSearch_Click(object sender, EventArgs e)
    {
        GetGraphData( new TwitterSearchNetworkGraphDataProvider() );
    }

    private void btnTwitterList_Click(object sender, EventArgs e)
    {
        GetGraphData( new TwitterListNetworkGraphDataProvider() );
    }

    private void btnYouTubeUsers_Click(object sender, EventArgs e)
    {
        GetGraphData( new YouTubeUserNetworkGraphDataProvider() );
    }

    private void btnYouTubeVideos_Click(object sender, EventArgs e)
    {
        GetGraphData( new YouTubeVideoNetworkGraphDataProvider() );
    }

    private void btnFlickrUsers_Click(object sender, EventArgs e)
    {
        GetGraphData( new FlickrUserNetworkGraphDataProvider() );
    }

    private void btnFlickrRelatedTags_Click(object sender, EventArgs e)
    {
        GetGraphData( new FlickrRelatedTagNetworkGraphDataProvider() );
    }

    private void GetGraphData(IGraphDataProvider oGraphDataProvider)
    {
        wbWebBrowser.GoHome();

        String sGraphData;

        if ( !oGraphDataProvider.TryGetGraphData(out sGraphData) )
        {
            return;
        }

        using ( StreamWriter oStreamWriter =
            new StreamWriter(TempXmlFileName) )
        {
            oStreamWriter.Write(sGraphData);
        }

        wbWebBrowser.Navigate(TempXmlFileName);
    }

    private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
    {
        File.Delete(TempXmlFileName);
    }

    private String
    TempXmlFileName
    {
        get
        {
            String sAssemblyPath = Path.GetDirectoryName(
                Assembly.GetExecutingAssembly().CodeBase);

            if ( sAssemblyPath.StartsWith("file:") )
            {
                sAssemblyPath = sAssemblyPath.Substring(6);
            }

            return ( Path.Combine(sAssemblyPath, "TempGetGraphData.xml") );
        }
    }
}
}

Apr 29, 2011 at 5:01 PM

Thank you, tcap479! Your solution works fine and is indeed much faster and more efficient.