Entries from May 1, 2013 - May 31, 2013

Friday
May312013

Using C# To Draw An OrgChart in Visio 2010  

I added a new sample to my NuGet package Visio C# Samples. It's a very straightforward sample of how to draw an org chart.

Some of the things it demonstrates

  • How to open a template-based visio document (such as an org chart)
  • Using the DropManyU API
  • Using the AutoConnect API
  • How to detect which version of Visio is being used

Notes:

  • The code works for both VIsio 2010 and Visio 2013.
  • Auto-positioning of the shapes is NOT covered. That is a separate problem I didn't want to cover in this example.

The code is shown below:

 

            var app = new IVisio.ApplicationClass();
            var docs = app.Documents;
            // Create a new OrgChart using the org chart template
            var doc = docs.AddEx("orgch_u.vst", IVisio.VisMeasurementSystem.visMSUS, 0,0);
            var page = app.ActivePage;
            // Get the masters
            bool is_visio_2013 = app.Version.StartsWith("15.");
            var orgchart_masters = doc.Masters;
            var position_master = orgchart_masters[is_visio_2013 ? "Position Belt" : "Position"];
            var dyncon = orgchart_masters["Dynamic Connector"];
            // three masters to drop
            var masters = new object[] { position_master, position_master, position_master };
            // three coordinates to make the drop
            var xy_array = new double[] {1,2 ,3,5, 6,2};
            // perform the drop of all shapes at once
            // and get the shape ids back out
            System.Array shape_ids_sa;
            page.DropManyU(masters, xy_array, out shape_ids_sa);
            var shape_ids = (short[])shape_ids_sa;
            // using the shape ids, get the shape objects
            var shape0 = page.Shapes.ItemFromID16[shape_ids[0]];
            var shape1 = page.Shapes.ItemFromID16[shape_ids[1]];
            var shape2 = page.Shapes.ItemFromID16[shape_ids[2]];
            // perform connections using the Dynamic Connection master
            shape0.AutoConnect(shape1, IVisio.VisAutoConnectDir.visAutoConnectDirNone, dyncon);
            shape1.AutoConnect(shape2, IVisio.VisAutoConnectDir.visAutoConnectDirNone, dyncon);

 

Sunday
May262013

Returning Collections from Functions in PowerShell: A tip for C# Developers learning PowerShell  

Previously in in April, I mentioned something C# developers should pay attention to when they start writing PowerShell code. Now, I want share another common PowerShell behavior that will be confusing at first for a C# developer and how to handle it. 

Let's start with this code:

 

$a = New-Object 'System.Collections.Generic.List[string]'
$a.Add("A")
$a.Add("B")
$a.Add("C")
$a.GetType().Name

 

 

What do you think will be printed by the last line? If you said "List<string>" you are correct –  however, it is displayed in a very ugly way:

List`1

Let's try another case:

$table = New-Object system.Data.DataTable
$col1 = $table.Columns.Add( "Col1", [string])
$col2 = $table.Columns.Add( "Col2", [int])
$table.Rows.Add( "bar", 0 )
$table.Rows.Add( "beer", 1 )
$table.Rows.Add( "baz", 2 )
$table.GetType().Name 

As expected the last line prints:

DataTable

Using Functions

Let's put that same code into functions:

function f1()
{
$arr = New-Object 'System.Collections.Generic.List[string]'
$arr.Add("A")
$arr.Add("B")
$arr.Add("C")
return $arr
}

function f2()
{
$table = New-Object system.Data.DataTable
$col1 = $table.Columns.Add( "Col1", [string]) | Out-Null
$col2 = $table.Columns.Add( "Col2", [int]) | Out-Null
$table.Rows.Add( "bar", 0 ) | Out-Null
$table.Rows.Add( "beer", 1 ) | Out-Null
$table.Rows.Add( "baz", 2 ) | Out-Null
return $table
}

Let's call those functions and check the return type

$a = f1
$a.GetType().Name
$t = f2
$t.GetType().Name

This piece of code will print out two things. Based on our previous experience we will expect to see:

List`1
DataTable

Here's what we actually see:

Object[]
Object[]

What happened?

If you come from a C# background this is very surprising. All I can say is that PowerShell doesn't always follow the semantics and behavior we are used to.

In this case, when a PowerShell function detects that you are retuning a enumerable object (such as a collection), it places each member of the collection on the pipeline as a separate item which in turn get collected into an Object[]

 

The Solution

This is going to look ugly, but the way to get around this is to return your collections as a single element array.

 

function f1()
{
$arr = New-Object 'System.Collections.Generic.List[string]'
$arr.Add("A")
$arr.Add("B")
$arr.Add("C")
return @(,$arr)
}

function f2()
{
$table = New-Object system.Data.DataTable
$col1 = $table.Columns.Add( "Col1", [string]) | Out-Null
$col2 = $table.Columns.Add( "Col2", [int]) | Out-Null
$table.Rows.Add( "bar", 0 ) | Out-Null
$table.Rows.Add( "beer", 1 ) | Out-Null
$table.Rows.Add( "baz", 2 ) | Out-Null
return @(,$table)
}

And now we will get what we expect:

List`1
DataTable

Wednesday
May012013

BioShock Infinite Screenshots  

No Spoilers, just some beautiful scenery. These are all gameplay screenshots –  no cutscenes.

Link to all screenshots

A few samples are below. Click on them to see the full-size original screenshots.

2013-03-26_00168

 

2013-03-26_00179

 

2013-03-30_00088

 

2013-03-30_00119

 

2013-04-07_00081