I saw a great post by the Visio Guy today ( Save Time & Simplify Your VBA Code With CallByName ) and thought it would be a good opportunity to demonstrate some of the simplification that you can achieve with the new features in C# 3.0 and using the VisioAutoExt library.
The point of his post was that you could use CallByName in VBA to reuse an algorithm – in this case applying a function to each element in a set of shapes. The sample code below does the same thing, but I hope you see how elegant it is in C# 3.0
ProcessShapes( page.Shapes , SomeMethod ); or you can even do this … ProcessShapes( page.Shapes , shape => { shape.SetFillForefroundColor( System.Drawing.Red ) } );
ProcessShapes( page.Shapes , SomeMethod );
or you can even do this …
ProcessShapes( page.Shapes , shape => { shape.SetFillForefroundColor( System.Drawing.Red ) } );
Below I’ve translated the source code from his original post into the C# 3.0 equivalent.
using System; using System.Collections.Generic; using System.Linq; using IVisio = Microsoft.Office.Interop.Visio; using VisioAutomation.Extensions; namespace VisioAutomationSamples { public partial class Demo { public static void sample4() { var visapp = new Microsoft.Office.Interop.Visio.ApplicationClass(); var doc = visapp.Documents.Add(new Isotope.Drawing.Size(10, 10)); var page = doc.Pages[1]; draw_stuff(page); ProcessShapes(page.Shapes, MakeRed ); ProcessShapes(page.Shapes, RotateLeft ); ProcessShapes(page.Shapes, SetText ); } public static void ProcessShapes( IEnumerable<IVisio.Shape> shapes , Action<IVisio.Shape> func) { foreach (var shape in shapes) { func(shape); } } public static void ProcessShapes( IVisio.Shapes shapes, Action<IVisio.Shape> func) { foreach (IVisio.Shape shape in shapes) { func(shape); } } public static void draw_stuff( IVisio.Page page) { // Draw some rectangles int num_rows = 3; int num_cols = 3; var grid = new Isotope.Drawing.LayoutGrid(page.GetRect(), num_rows, num_cols, false); var cells = grid.EnumCells(num_rows, num_cols); var shapes = cells.Select(c => page.DrawRectangle(c.rect)).ToList(); } public static void MakeRed( IVisio.Shape shape ) { shape.SetFillForegroundColor( System.Drawing.Color.Red ); } public static void RotateLeft( IVisio.Shape shape ) { if ( shape.OneD == VisioAutomation.VisUtil.BoolToShort(false) ) { double angle = shape.CellsSRC(VisioAutomation.VisProps.ShapeRotation) .get_Result(IVisio.VisUnitCodes.visDegrees); double new_angle = angle + (45.0*System.Math.PI/180.0); shape.CellsSRC(VisioAutomation.VisProps.ShapeRotation).ResultIU = new_angle; } } public static void SetText(IVisio.Shape shape) { shape.Text = "Hello World"; } } }
using System; using System.Collections.Generic; using System.Linq; using IVisio = Microsoft.Office.Interop.Visio; using VisioAutomation.Extensions;
namespace VisioAutomationSamples {
public partial class Demo {
public static void sample4() { var visapp = new Microsoft.Office.Interop.Visio.ApplicationClass(); var doc = visapp.Documents.Add(new Isotope.Drawing.Size(10, 10)); var page = doc.Pages[1];
draw_stuff(page);
ProcessShapes(page.Shapes, MakeRed ); ProcessShapes(page.Shapes, RotateLeft ); ProcessShapes(page.Shapes, SetText );
}
public static void ProcessShapes( IEnumerable<IVisio.Shape> shapes , Action<IVisio.Shape> func) {
foreach (var shape in shapes) { func(shape); } }
public static void ProcessShapes( IVisio.Shapes shapes, Action<IVisio.Shape> func) { foreach (IVisio.Shape shape in shapes) { func(shape); } }
public static void draw_stuff( IVisio.Page page) { // Draw some rectangles int num_rows = 3; int num_cols = 3; var grid = new Isotope.Drawing.LayoutGrid(page.GetRect(), num_rows, num_cols, false);
var cells = grid.EnumCells(num_rows, num_cols); var shapes = cells.Select(c => page.DrawRectangle(c.rect)).ToList(); }
public static void MakeRed( IVisio.Shape shape ) { shape.SetFillForegroundColor( System.Drawing.Color.Red ); }
public static void RotateLeft( IVisio.Shape shape ) { if ( shape.OneD == VisioAutomation.VisUtil.BoolToShort(false) ) { double angle = shape.CellsSRC(VisioAutomation.VisProps.ShapeRotation) .get_Result(IVisio.VisUnitCodes.visDegrees);
double new_angle = angle + (45.0*System.Math.PI/180.0);
shape.CellsSRC(VisioAutomation.VisProps.ShapeRotation).ResultIU = new_angle; }
public static void SetText(IVisio.Shape shape) { shape.Text = "Hello World"; }