| More
All posts by andrew troelsen
 


Expression Blend as a Better Venn Diagramming Tool

OK, this title is not meant to be taken too literally. But the fact remains that the Blend IDE does have some useful ways to perform Venn-like operations on graphically rendered data.

First question: Why would you care?  Well, as it turns out, many custom UserControls begin life as simple vector-graphics which are rendered with the Shape tools (pen, pencil, line, etc) and tweaked using the Properties window.

As you are building such a rendering, the IDE will capture pen and pencil strokes using a <Path> element, and members of System.Windows.Shapes for rectangles, circles and lines.  For example, assume the following collection of objects on a WPF main window:

image

If you were to examine the XAML, you would find something such as the following:

Code Snippet
  1. <Grid x:Name="LayoutRoot">
  2. ????<Rectangle Fill="#FFF4F4F5" HorizontalAlignment="Left" Height="102" Margin="93,104,0,0" Stroke="Black" VerticalAlignment="Top" Width="94"/>
  3. ????<Ellipse Fill="#FFB266C4" HorizontalAlignment="Left" Height="90" Margin="144,56,0,0" Stroke="Black" VerticalAlignment="Top" Width="141"/>
  4. ????<Path Data="M309,146 C312.9974,153.42375 327.83819,145.16181 316,157 308.306,164.694 300.44568,164.73715 288,167 272.18419,169.8756 257.07965,169 241,169 241,192.88331 245.44728,208.70181 221,225 198.3426,240.10493 176.35947,237.47189 149,232 139.06896,230.01379 120.68398,243.94709 142,270 162.84782,295.48066 192.04381,292 231,292 256.11759,292 272,295.23879&#xd;&#xa;272,251 272,232.79339 285.87442,229.22512 312,224 326.54263,221.09147 327.62914,223.96357 338,211 343.95409,203.55739 346.32948,183.5472 341,172 333.43652,155.61245 328.80223,157.37715 313,148" Fill="#FF69C042" Margin="134.133,104,168,124" Stretch="Fill" Stroke="Black"/>
  5. </Grid>

Now, using Blend, you can select multiple shape objects (via  Shift + Click) and then activate the context menu on your selection.  Here you will find a Combine menu tem, which exposes a series of Venn-like operations:

image

For example, if you were to pick the Unite option for each selected shape, your resulting image would appear as so:

image

And the previous three elements have been combined into a single <Path> object:

Code Snippet
  1. <Path Data="M150.77036,85.421501 L148.74716,86.002968 C140.37247,88.254791 131.16498,89.5 121.5,89.5 111.83501,89.5 102.62753,88.254791 94.252838,86.002972 L93.5,85.786606 93.5,138.79258 94.053612,138.78882 C106.61694,138.54271 118.46339,135.52435 130.50014,127.49986 148.8356,115.27625 150.91786,103.32245 150.81303,88.033772 z M225.23241,52.076152 L225.59306,52.121458 C228.37724,52.402526 230.62875,52.309617 229.83183,54.242061 L229.71127,54.485531 229.14326,54.191226 C227.95673,53.57149 226.69139,52.894059 225.33565,52.134794 z M218.50015,48.500001 L222.50015,50.499996 C222.99397,50.793032 223.47688,51.075187 223.94933,51.347355 L225.23241,52.076152 224.2794,51.956441 C222.05745,51.608034 219.74934,50.819918 218.50015,48.500001 z M121.5,0.5 C160.15993,0.5 191.5,20.423328 191.5,45.000001 191.5,54.216252 187.0928,62.778128 179.5451,69.880373 L177.75679,71.479061 179.9185,71.396465 C185.73831,71.12915 191.56923,70.578312 197.50015,69.499966 209.94583,67.237118 217.80615,67.193968 225.50015,59.499981 227.71982,57.280325 229.00154,55.767313 229.59267,54.725051 L229.71127,54.485531 230.30397,54.792619 C240.14322,59.853534 244.35483,61.185095 250.50015,74.499956 255.82964,86.047142 253.45424,106.05729 247.50015,113.49989 237.1293,126.46344 236.04279,123.59135 221.50015,126.49987 195.37457,131.72498 181.50015,135.29324 181.50015,153.49982 181.50015,197.73853 165.61774,194.49976 140.50014,194.49976 101.54394,194.49976 72.347946,197.98041 51.50013,172.49979 44.172749,163.54411 41.536594,156.02055 41.635677,150.08342 L41.670158,149.5 0.5,149.5 0.5,48.499997 51.714752,48.499997 51.704113,48.42385 C51.568863,47.293838 51.5,46.152031 51.5,45.000001 51.5,20.423328 82.840065,0.5 121.5,0.5 z" Fill="#FFF4F4F5" Margin="93,56,277.035,190.84" Stretch="Fill" Stroke="Black"/>

Blend is plump-full of useful shortcuts like these, and I'll post other tidbits over time.

Happy Blending.


Posted by: Andrew Troelsen
Posted on: 7/20/2010 at 9:07 AM
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Thoughts on "blended classes"

About 1 year ago, Intertech began offering "blended classes".  This training mode allows us to hold a class which is attended by folks in our physical classroom (in lovely Eagan, MN) as well as people from around the US.  Those who are attending remotely typically use a land-line phone system (or in some cases, VOIP) to hear the lecture, and webex to view the slides, demos and quizzes.

At first, I was fearful that this mix of student types could hurt both groups of people. My first fear was that the remote attendees could become isolated. However, since Intertech has training rooms equipped with SmartBoards (you know, the cool white boards you can control with your hand, write on with "virtual pens" and so on), the remote folks have much more engaging eye candy- far more than a bunch of random PowerPoint slides. The use of the SmartBoard seems to keep the remote folks more connected than I realized. The local folks also seem to have a fair share of "oohs" and "aahs".

I was also fearful that local and remote students might have problems hearing each other.  Thankfully, our training rooms are equipped with built in speakers / mics, so again, things are fairly smooth.

To be honest, teaching a blended class feels little different than teaching a class where all students are local to the classroom.  These days, I tend to feel like something is "missing" if we don't have at least 1 remote student.  The mixing of student types tends to make everyone a bit more interactive, which is fantastic.

Not everything is flawless however. We have had a few times where we lost connections to remote students due to oddball issues in the area.  Once, some city workers basically took down our internet connectivity more much of a work day.  Obviously this was no good for anyone.  Beyond such issues, the core infrastructure (webex, mics, land-lines, etc) has been quite solid.

So, as an FYI, if you are interested in a standard Intertech class, but don't live in state, do be aware that any of our classes can be attended remotely. This can be very beneficial to the attendees.  Not only do they reduce some travel and hotel expenses, but they can be "close to home base" to respond to any fires at work which pop up.

And, I suppose you *could* attend class in your PJs if you really want to (don't worry, we don't bother with any web cams).


Posted by: Andrew Troelsen
Posted on: 7/8/2010 at 10:24 AM
Tags:
Categories: Business
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

The Role of Select and Direct Select in Blend

The Blend IDE can be a strange and mysterious place for many developers. As you most likely already know, Blend, in general, is a tool to generate XAML for WPF and Silverlight applications, using a fancy graphical environment.

Similar to Visual Studio, Blend maintains a pallet of controls which can be placed on the visual designer surface, after which point they can be configured using the Properties window.

Naturally, as you are creating a UI, you may need to relocate or reposition items on the designer, and this simple task smacks you right into the odd distinction of a "Selection" and "Direct Select". If you examine the Blend Tools pallet, you will see two selection icons to represent each possibility:

image

Now, assume you have placed a Button control and a rendered geometry (via the Pencil tool) onto the designer.

If you wish to simple select an item for the purpose of resizing, moving or rotation, you will want to use the Select option (press the V key as a keyboard shortcut).  Once you have done so, you will be able to tweak the selected item as you see fit:

image

This being said, what is a "Direct Selection" used for (press the A key as a keyboard shortcut).  Well, the answer is "it depends".  If you perform a direct select on a rendered vector graphic, it will allow you to redefine the path itself using a set of pull points:

image

If you perform a direct select on a ContentControl derived item (such as a Button) it provides a way to drill into the internal content of the control. This can be helpful if you have (for example) a Button which set the Content property to a layout manager (a Canvas perhaps) which contains some number of sub items. In this case, a direct select will allow you to edit the internal aspects of the Button, rather than its general dimensions and placement.

Enjoy!


Posted by: Andrew Troelsen
Posted on: 6/29/2010 at 1:48 PM
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Building a Better Brush with Blend

As odd as it may seem to those new to WPF and Silverlight development, ?brushes? are a key aspect of these programming APIs. These seemingly uneventful objects serve as building blocks for interactive geometries, custom styles, custom control templates, resource items and whatnot.

If you require a simple solid colored brush (say, a ?red? brush to fill in the background of a widget), your job could not be any easier. Simply assign a string value to a brush-compatible property:

<Ellipse x:Name="myCircle" Fill="LightGreen"
Stroke="DarkGreen"
StrokeThickness="4"
Height="50" Width="50"/>

Here, the Stroke and Fill properties have been assigned to string values that map to a built in set of known colors. Behind the scenes, these string objects are transformed into a corresponding SolidColorBrush object using a built-in type converter.

Now, if you require a more exotic brush (such as a LinearGradientBrush or RadialGradientBrush), typing in the required markup is much more taxing. Consider the following update to our Ellipse object, now making use of a RadialGradientBrush object, containing a set of gradient stops.

<Ellipse x:Name="myCircle"
Stroke="DarkGreen"
StrokeThickness="4"
Height="50" Width="50">
<Ellipse.Fill>
<RadialGradientBrush GradientOrigin="0.65,0.61">
<GradientStop Color="#FF83D688" Offset="0"/>
<GradientStop Color="#FF74D47B" Offset="1"/>
<GradientStop Color="#FF14721A" Offset="0.491"/>
</RadialGradientBrush>
</Ellipse.Fill>
</Ellipse>

As you might imagine, it would be a massive pain in the neck to type in GradientStop object data manually using Visual Studio (even with this relatively simple RadialGradientBrush):


Thankfully, Expression Blend has a wonderful brush editing experience. Using the Properties window, you are able to easily add, remove and configure GradientStop objects using a dedicated editor. Assume you have added an Ellipse object to the Blend designer surface. Once you have selected this item, you will find the following editor.

Notice the location of the mouse cursor in the previous screen shot. This row of buttons allows you to select which brush category you are interested in working with (no brush, solid colored brush, gradient brush, etc). Beyond the ?no brush? option, the remaining options allow you to use the color editor (located below the ?brush selection row? area) to select ARGB values.

When you select the ?Gradient brush? option, the brush editor changes just a tad. Most specifically, you have a new area below the color editor, which allows you to add, remove and configure GradientStop objects.

By default, you will be given two ?thumbs? that represent your first two gradient stop settings, which are set to the colors black and white. Below this editor, you will find a few small buttons on the lower left which allow you to toggle between radial or linear gradient brushes:

When you click on either of the gradient stop thumbs, you can change the underlying color (and the generated HEX value in the related markup). Likewise, if you slide these thumbs on the gradient editor, you are able to control the Offset property of the current GradientStop.

If you wish to add additional gradient stops, simply click within a blank area on the gradient stop strip. Removing a gradient stop you no longer require is a bit unintuitive (if you ask me?); you cannot ?right click? on a thumb to activate a ?delete? menu option. Rather, you simply drag a given thumb off the gradient strip editor. Once you have done so, it will vanish from view (and markup).

Once you have defined your gradient stops, you may then wish to change GradientOrigin property of the RadialGradientStop (or LinearGradientStop) object, which controls when the color blending will begin rendering. To do so, you will move off the brush editor itself, back to the designer surface. Ensuring the item using your brush is selected (the Ellipse in this example), press the G key (not Ctrl+G mind you, just G). This will add a gradient origin editor to the surface, which can be moved around to control the starting point:

Last but not least, Blend makes it very easy to store that ?perfect? brush as an application object resource. You?ll notice on the Brush editor of the Properties window, a button which reads ?+ Brush?. Once you click on this option, you are able to specify a new named resource, and the location you wish to store it (application level, resource file, etc).

That wraps up this (long overdue) blog entry. Hope you have gained a bit of insight regarding very useful (and often mysterious) Blend IDE.


Posted by: Andrew Troelsen
Posted on: 6/28/2010 at 1:47 PM
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Expression Blend for Developers: Video Tutorial

Hey all. A while back, I gave a public talk at the Microsoft offices here in Minneapolis on Expression Blend. It was a talk that illustrated a number of features that developers would need to know to get up to speed on the tool.

Given the shorter work week (happy Fourth of July!) I don't think I'll be able to get the first "real" blog post on Blend posted this week. So, please enjoy the following tutorial on some Blend basics.

You can view it online here.

I'll follow up with more Blend coverage next week.

Enjoy!


Posted by: Andrew Troelsen
Posted on: 6/28/2010 at 1:46 PM
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

The Role of, and Need For, Blend

When WPF first appeared on the programming landscape, (and once SL moved to version 2.0 and became something we could be proud of), it was clear that typing gobs of XML was in our future. 

Now, if you are anything like me, you may have thought that you could muddle through and simply leverage Visual Studio has you XAML editor of choice.  While you COULD do so, you would soon get massive hand cramps, as earlier versions of VS had very limited support for XAML editing, beyond simple code completion. 

Now that Visual Studio 2010 is here, many folks assume that this version of the IDE has ALL the features you could possibly need, it is simply not the case. VS2010 does have a number of improvements to be sure.  You can now extract resources, define complex brushes, establish (some) data bindings and so on, all from the comfort of your Properties window.  Furthermore, the WPF and SL designers have true drag-and-drop control placement.

But...

If you want to define animations, 3D graphics or generate UserControls on the fly, Visual Studio is not enough. And that is where Expression Blend comes in.

When Blend was first released, it was marketed as a tool for graphical artists. Now, I am not so sure. It seems that the line between programmer and graphical artist is blurring. While nobody should expect a programmer to generate top-notch graphics (anymore than a graphical artist should not be expected to generate C# code), it is clear that the modern day WPF/SL programmer *should* know the basics of the Blend IDE.

As suggested, Blend is a very elaborate XAML editor. Unlike VS 2010, Blend *does* allow you to work with complex animations, extraction of UserControls from graphical data, edit default styles, define visual states for custom controls, generate 3D effects, apply animation easings and dozens of other feature that VS 2010 simply does not support. 

So. the short answer is, unless you *really* like typing XML, you will need to flip between VS 2010 and Blend when you are building a WPF / SL program.  

Given this, the next several blog posts will address the key features of Blend from a programmer's point of view.  If you don't have your own personal copy of Blend, be sure to download an evaluation copy here.

My next blog post will start at the very beginning of working with Blend.  Look for it in a few days!

 


Posted by: Andrew Troelsen
Posted on: 6/21/2010 at 11:28 AM
Tags:
Categories: .NET
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Top 10 Things Seasoned .NET Developers Understand or 10 Things New .NET Developers Need to Know

My coworker at Intertech (Jim White) wrote an interesting blog post which addressed the "10 topics advanced Java programmers need to know" (he's a Java-guy, but don't hold that against him ;-). I liked his article, so I thought I'd offer up a .NET version of the same post.  Here it goes, and thanks Jim for the idea!  By the way, these are *not* any any specific order...

10) LINQ

At first, LINQ was seen by many to be a interesting shortcut for grabbing data from a container.  Nowadays however, LINQ is everywhere.  LINQ to XML, LINQ to EF, PLINQ and LINQ to Objects are common place.  If you want to show your team mates you are up to speed on core .NET technologies, understanding LINQ should be on the top of your list of ToDos.

9) WPF (and therefore Silverlight)

Regardless if you are a "Web Person" or a "Desktop Person", Microsoft's current GUI APIs are quickly replacing older frameworks, especially Windows Forms.  Both WPF and Silverlight use the same core body of tech, so when you understand 1, the other is close behind.

8) The Blend IDE

I was a man who was fearful of Blend early on.  In fact, I wore my fingers to the bone typing in XAML by hand.  Trust me, if I can get over the Blend fear-zone, any one can.  If you are doing WPF or Silverlight, usnig Blend makes your work much easier, especially when working with templates, animations or graphics.

7) TPL

The Task Parallel Library is a new .NET 4.0 threading / multicore API.  Using TPL (and PLINQ) you can very easily add multithreaded functionality to your applications, using a framework which hides a good number of the low level details. Thanks thread pool!

6) Lambdas

The C# => operator, or the VB Sub/Function statements, can seem to be quite terse at first glance. However, lambdas are a great shortcut for working with delegates.  If you are serious about learning LINQ and the TPL, you *need* to be confortable with lambdas.

5) WF 4.0

OK, I know.  WF 3.0-3.5 had some warts.  But honest, WF 4.0 is a massive step in the right direction.  A whole new assembly stack, new designers, new engine and new activities make the process of modeling business processes clean and simple.  And, WF 4.0 is based on XAML!

4) Knowing if you REALLY need That Pattern

Design patterns *can* help you write easy to maintain code....or they can add layers of unnecessary complexity.  We programmers love the latest and greatest to be sure, but I have seen too many people cram patterns into projects that just don't need them.  Case in point?  ASP.NET MVC.  Yes, it is great for testing web sites, but there are ways to do so without MVC.  Don't use a pattern because it is the latest buzz word.  Use it because it will make your life better.

3) ADO.NET EF

The Entity Framework is a slick object model over relational database logic, which favor LINQ queries over T-SQL queries. While the connected and disconnected layers are certainly still part of the picture, the EF model can really simplify common database activities....and the VS 2010 designers are very solid.

2) Use of Dynamic Data

The DLR allows you to opt-into scripting like functionality, within a statically typed language. If you are doing any sort of COM interop, dynamic assembly generation or reflection tasks, dynamic data can reduce the amount of code you will need to write by a *great* deal.  Just watch your typing...

1) The .NET Type System

In a rush to get software out the door ASAP, many programmers "skip" over the foundational nuts and bolts, and google for the next "how do I make my grid look like this" sort of answer.  Google is great, but you really owe it to yourself to be solid on the ins and outs of classes, interfaces, structures, enums and delegates. These are the bread and butter aspects of every possible .NET application and API.

So, thanks again Jim for the idea. Hope to see some of you in class where we can learn about these (and many other) .NET topics

 


Posted by: Andrew Troelsen
Posted on: 6/7/2010 at 4:47 PM
Categories: .NET
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (3) | Post RSSRSS comment feed

A Review of VB Event Handling (WithEvents, AddHandler and AddressOf)

When you are building an application using VB, you will most certainly need to hook into various event sources.  While events are very common when you are constructing a GUI application (WPF, ASP.NET, Windows Forms), they are also very important for non-UI tasks such as working with threads, callbacks from database operations, and other tasks.

As it turns out, VB has a few "oddities" regarding how to hook into a given event, so I wanted to do a quick blog post which will hopefully clarify our choices.

First of all, when you are declaring a field of a Class, Structure or Module, you have the option of making use of the WithEvents keyword.  When you do so, you are able to selectively hook into events of interest using the Handles clause on a given class method. One part of this puzzle which is hidden from view is the fact that each and every .NET event is defined in termes of a related delegate.  As you may know, the .NET delegate type allows us to capture, in a strongly typed manner, the address of another method. Given this point, the method that uses the Handles clause must match the underlying delegate definition, or you will receive compile time errors!

Here is a simple example of capturing the Click event of the Windows Forms Button class.  Take note that the method receiving the event notification takes an Object as the first parameter, and a EventArgs as the second, given that the Click event has been defined in terms of a system delegate named System.EventHandler.

 Class MainWindow
 
Inherits Form

  ' Inform the Button we are interested in listening to
  ' events.
  Private WithEvents btnClickMe As Button

  Public
Sub New()
    btnClickMe =
New Button With {.Height = 100,
      .Width = 100, .Text =
"OK!"}
   
Me.Controls.Add(btnClickMe)
  End Sub

  Private Sub btnClickMe_Click(ByVal sender As Object,
   
ByVal e As System.EventArgs) Handles btnClickMe.Click
   
MessageBox.Show("Clicked!")
 
End Sub
End
Class

Now, one gotchya is that the WithEvents keyword can only be used for fields (local variables need not apply). When you wish to handle an event for a local variable, you are required to use the AddHandler statement.  Here, you will specify the event name and method to call (via the AddressOf operator).  However, in this case the Handles clause is not used.  Here is a re-working of the previous class which illustrates these points: 

Class MainWindow

Inherits Form
 
Public Sub New()
   
Dim btnClickMe As Button
   
btnClickMe = New Button With {.Height = 100,
      .Width = 100, .Text =
"OK!"}

   
AddHandler btnClickMe.Click, AddressOf btnClickMe_Click
    
Me.Controls.Add(btnClickMe)
 
End Sub
...
End Class

Of course, with the release of .NET 4.0, VB has full support for lambda expressions.  This is yet another way to hook into event sources, which was covered in a previous blog post.


Posted by: Andrew Troelsen
Posted on: 6/1/2010 at 10:03 AM
Categories: .NET
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

C# and the .NET Platform, 5th Ed.

Quick blog post this week to let people know that the 5th Edition of my C# book is in the stores!

C# 2010 and the .NET 4.0 Platform tops in at more than 1700 pages (eek!).

But there are a number of new topics, extended topics, additional examples and other goodies. Here is a hit list of the big topics:

  • Coverage of the C# dynamic keyword and DLR
  • Coverage of the ADO.NET Entity Framework / LINQ to Entities
  • Coverage of C# 2010's improved COM interop
  • Coverage of the TPL and PLINQ
  • Deeply expanded coverage of WPF
  • Deep coverage of Expression Blend
  • Coverage of WF 4.0 (which is totally different from the previous WF API)
  • The new WCF 4.0 bits.
  • etc, etc, etc.

As before, Apress is offering deals for a digital copy of the book if you buy the printed copy.  Check out the following link for more details.

Be back next week with some new tech-posts.  Thinking of starting a long blog tutorial about Expression Blend......hummmm.....

Happy coding,

Andrew

 


Posted by: Andrew Troelsen
Posted on: 5/21/2010 at 3:14 PM
Categories: .NET
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Simple COM Interop with Dynamic

The C# 2010 dynamic keyword can be used for a variety of reasons, some of which are a tad esoteric.  However, there is a very practical use of this new language feature, specifically the (radical) simplification of COM interop programming. By default, when you import a COM library into a VS 2010 project (configured to target .NET 4.0), every COM VARIANT is automatically mapped to a dynamic data type.

This behavior greatly decreases the need to cast data types and drill into low level interop primitives (such as the underlying get_ / set_ methods).

Furthermore, thanks to C# 2010 optional arguments, you no longer need to author reams of Type.Missing tokens when specifying missing values.

To showcase the distinction, assume you wish to map some data in a List to Microsoft Excel.  Before .NET 4.0, you might author code such as the following:

Code Snippet
  1. static void ExportToExcel2008(List<Car> carsInStock)
  2. {
  3.     Excel.Application excelApp = new Excel.Application();
  4.  
  5.     // Must mark missing params!
  6.     excelApp.Workbooks.Add(Type.Missing);
  7.  
  8.     // Must cast Object as _Worksheet!
  9.     Excel._Worksheet workSheet = (Excel._Worksheet)excelApp.ActiveSheet;
  10.  
  11.     // Must cast each Object as Range object then call
  12.     // call low level Value2 property!
  13.     ((Excel.Range)excelApp.Cells[1, "A"]).Value2 = "Make";
  14.     ((Excel.Range)excelApp.Cells[1, "B"]).Value2 = "Color";
  15.     ((Excel.Range)excelApp.Cells[1, "C"]).Value2 = "Pet Name";
  16.  
  17.     int row = 1;
  18.     foreach (Car c in carsInStock)
  19.     {
  20.         row++;
  21.         // Must cast each Object as Range and call low level Value2 prop!
  22.         ((Excel.Range)workSheet.Cells[row, "A"]).Value2 = c.Make;
  23.         ((Excel.Range)workSheet.Cells[row, "B"]).Value2 = c.Color;
  24.         ((Excel.Range)workSheet.Cells[row, "C"]).Value2 = c.PetName;
  25.     }
  26.  
  27.     // Must call get_Range method and then specify all missing args!.
  28.     excelApp.get_Range("A1", Type.Missing).AutoFormat(Excel.XlRangeAutoFormat.xlRangeAutoFormatClassic2,
  29.             Type.Missing, Type.Missing, Type.Missing,
  30.             Type.Missing, Type.Missing, Type.Missing);
  31.  
  32.     // Must specify all missing optional args!  
  33.     workSheet.SaveAs(string.Format(@"{0}\Inventory.xlsx", Environment.CurrentDirectory),
  34.         Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
  35.         Type.Missing, Type.Missing, Type.Missing);
  36.     excelApp.Quit();
  37.     MessageBox.Show("The Inventory.xslx file has been saved to your app folder", "Export complete!");
  38. }

Notice in particular the grimy casting operations (Excel.Range, and so forth). 

Now, here is the same code once again, using the new features of C# 2010:

Code Snippet
  1. static void ExportToExcel(List<Car> carsInStock)
  2. {
  3.     // Load up Excel, then make a new empty workbook.
  4.     Excel.Application excelApp = new Excel.Application();
  5.     excelApp.Workbooks.Add();
  6.  
  7.     // This example uses a single workSheet.
  8.     Excel._Worksheet workSheet = excelApp.ActiveSheet;
  9.  
  10.     // Establish column headings in cells.
  11.     workSheet.Cells[1, "A"] = "Make";
  12.     workSheet.Cells[1, "B"] = "Color";
  13.     workSheet.Cells[1, "C"] = "Pet Name";
  14.  
  15.     // Now, map all data in List<Car> to the cells of the spread sheet.
  16.     int row = 1;
  17.     foreach (Car c in carsInStock)
  18.     {
  19.         row++;
  20.         workSheet.Cells[row, "A"] = c.Make;
  21.         workSheet.Cells[row, "B"] = c.Color;
  22.         workSheet.Cells[row, "C"] = c.PetName;
  23.     }
  24.  
  25.     // Give our table data a nice look and feel.
  26.     workSheet.Range["A1"].AutoFormat(
  27.         Excel.XlRangeAutoFormat.xlRangeAutoFormatClassic2);
  28.  
  29.     // Save the file, quit Excel and display message to user.
  30.     workSheet.SaveAs(string.Format(@"{0}\Inventory.xlsx", Environment.CurrentDirectory));
  31.     excelApp.Quit();
  32.     MessageBox.Show("The Inventory.xslx file has been saved to your app folder", "Export complete!");
  33. }

Nice, eh? I'm sure you'd agree that simplification is always a good thing...


Posted by: Andrew Troelsen
Posted on: 5/16/2010 at 8:59 PM
Tags:
Categories: .NET
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed