Sunday, January 31, 2010

Avoid Silverlight toolkit DLL hell

Avoid Silverlight toolkit DLL hell


Avoid Silverlight toolkit DLL hell

Posted: 31 Jan 2010 03:58 AM PST

Maybe this can sound you a bit obvious, but it's something that I have found in several teams / projects, and I think it's worth to point it out. When you start your own project as a solo developer, or build a small team to work together it's quite common...( read more )...(read more)

Reading MP3 metadata with Silverlight and drag-drop

Posted: 30 Jan 2010 02:38 PM PST

I'm working on a little sample application for music management in Silverlight using WCF RIA Services and some other new Silverlight 4 features. One thing that I wanted to add to the application was the ability to drag an audio file and either lookup...( read more )...(read more)

Reading MP3 metadata with Silverlight and drag-drop

Posted: 30 Jan 2010 02:38 PM PST

I'm working on a little sample application for music management in Silverlight using WCF RIA Services and some other new Silverlight 4 features. One thing that I wanted to add to the application was the ability to drag an audio file and either lookup Read More......(read more)

Saturday, January 30, 2010

Silverlight in “Advert Worth Watching” Shocker! :-)

Silverlight in “Advert Worth Watching” Shocker! :-)


Silverlight in “Advert Worth Watching” Shocker! :-)

Posted: 30 Jan 2010 11:54 AM PST

There's an ad over on MSN UK for the new "Mass Effect 2" game and it's very distinctive as it's done in Silverlight and has some really cool aspects to it such as making use of Smooth Streaming and DeepZoom. It's not often ( well, ever ) that I've linked...( read more )...(read more)

Friday, January 29, 2010

Silverlight 4 : COM Interop..Endless Opportunities

Silverlight 4 : COM Interop..Endless Opportunities


Silverlight 4 : COM Interop..Endless Opportunities

Posted: 29 Jan 2010 10:10 AM PST

These days offline sessions keeping me very busy and because of that I am not able to come here frequently.Well, Today I am going bit ahead and will be talking about COM Interop capabilities with version 4 Beta with some small examples and few lines of...( read more )...(read more)

MS Days 2010

Posted: 29 Jan 2010 07:40 AM PST

Microsoft Bulgaria announced the dates for this year MS Days event – 30-31 March. The agenda is not finalized yet, but you can see all the speakers http://msbgregistration.com/Lecturers.aspx, become a fan in event Facebook Page, or follow the tweets....( read more )...(read more)

MVVM – It’s Not Kool-Aid*

Posted: 28 Jan 2010 06:15 PM PST

MiniTutorialLogo

 

 

 

 

SLHvpLogo

 

Okay, first, understand that I'm in the position of running through the streets yelling at folks "c'mere! ya' gotta see this!" and what I'm pointing to is the incredible new invention of… a laptop computer. Something that is undeniably amazing and cool, but everyone else on my block has already got one.

Second, and much worse, I'm about to show you how I used a "pattern" that you either have already embraced, or that you've been avoiding like the plague because the folks who are running around shouting "MVVM! MVVM!" sound just like the folks who were running around shouting "MVC! MVC!" and "OOP! OOP!" and "COM! COM!"…  you get the idea.

Many of us are still recovering from the last five fads that caused us to go out and buy dozens of books and break our head on the latest/greatest trend, only to have it be "oh so last year" by the time we fully grokked it.

 

Drinking The Kool Aid*

Kool Aid Man

 

But this is different. Honest.

Here are three heretical assertions about MVVM:

  1. It is not all that different from what you are already doing
  2. It is not hard to understand or to do
  3. You will write better code, and you'll write less code.

 

Typically, when a pattern or practice comes along, there is a steep learning curve, and the cognoscenti will tell you that it takes a very long time to truly master the approach. Feh. And not so, at least not this time. Let's go over the assertions above, and I'll explain, briefly, what you need to know to profit from MVVM.

Disclaimer: I'm not saying this is all you'll ever need to know about MVVM, I'm saying if you know this, you can benefit from MVVM on any non-trivial application, while you're learning more.

While I'm disclaiming, please note that I'm writing very specifically about a Silverlight 4 project and that I've been coding with MVVM for about a half hour.

 

It's Not All That Different and It's Not That Hard

We've been talking about n-tier development, decoupling, scoping, visibility and related topics since at least 1990. I'm pretty sure that when they were cracking the Enigma machine in World War II, they discussed decoupling the code-breaker module from the UI (did they have UI then?)

MVVM, at its heart has three core concepts, only the third of which is new, but that difference is all the difference in the world when you're writing a Silverlight application that you want to be able to maintain and create unit tests for (Yes, I owe a blog post on Test-Driven design, but one glass of grape juice at a time).

MVVMSketch

 

 

Core Concept #1:  Separate your User Interface concerns (View) from your Business objects and behaviors (View Model) and from your data/persistence layer (Model).

Core Concept #2 Don't Look Up

We tend to conceptualize the View (User Interface objects) at the top, the ViewModel (objects that provide the UI with its data and behaviors) in the middle and the model (often the persistence layer) at the bottom.  The View can know about the ViewModel, the ViewModel about the Model, and the Model, like the cheese, stands alone.

Core Concept #3 – And this is the killer: Binding.

In MVVM the mechanism for the ViewModel to provide data to the View, is for the View to set the ViewModel as its DataContext.  That is so cool; it takes a while to realize the implications.  Further, we don't just bind data, as I'll show below.

Why Would You Want To Do That, & What Does It Cost?

The huge advantages of using binding and making the VM the datacontext for the View is that you write less code and, equally important, your behaviors and state are all separated from the UI and thus you have enormously increased the testability of your application. (It is a bear to try to test a UI object because the pesky UI gets in the way. ViewModels have no UI, they have just the things you want to test: "does it behave as expected? and is the data correct at any given instant?"

So, the cost is negative; that is, by adopting MVVM you don't work harder, you work less, and in exchange for doing less, your code is easier to write, to read, to maintain and to test. Not bad.

 

Names

Simplifying is one thing, over-simplifying another, and there is an elegance in the chosen names. 

The Model is that which the application is modeling. Calling this the database layer or the persistence layer loses site of the fact that the  model might be virtually any time of information in virtually any format.

Calling the top layer the View, rather than the User Interface is important both to emphasize that it is just one of many possible views of the model, and to keep clear that the User Interface comprises both the appearance and the behaviors and the View is concerned only with the appearance.

The ViewModel is the bridge between the Model and the View; and the ViewModel thus owns responsibility for binding the relevant data to the view and for handling user actions appropriately, whether the response is in the widget, elsewhere in the View or in other parts of the application.

A Practical Example

To see this at work, we'll start by creating a new Silverlight Application. (Complete source code is available here)

Immediately add a new UserControl and name it PeopleView. Here is the Xaml for the UserControl:

<UserControl x:Class="MVVMWithBehaviors.PeopleView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">

<Grid x:Name="LayoutRoot" Background="White">
<ListBox Name="Names"
Background="Beige"
Width="200"
Height="250"
HorizontalAlignment="Center"
VerticalAlignment="Center"></ListBox>
</Grid>
</UserControl>
For completeness, here is the Xaml for MainPage.xaml
<UserControl x:Class="MVVMWithBehaviors.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:me="clr-namespace:MVVMWithBehaviors"
d:DesignHeight="300" d:DesignWidth="400">

<Grid x:Name="LayoutRoot" Background="White">
<me:PeopleView HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" />
</Grid>
</UserControl>

 

Note: If my solution were named HVP I'd have the following projects to support this model:

HVP
HVP.Web
HVP.Model
HVP.ViewModel
HVP.View
HVP.Tests

The advantage, for me, is that when I wish to touch a method or property in another class, the compiler will let me know if I'm crossing a project boundary (I'll need a using statement) and that is a great time to double check that I have my visibility correct (e.g., a class in the View project can include ViewModel but not vice versa)
 
Next we'll create PeopleViewModel, as a class.  The job of this class is to expose the properties (and as you'll see, the methods) that we want the View to bind to.  Specifically, we want the ListBox within the view to bind its ItemsSource property to a collection of People, and we want the Person object to have a property which will display the name of that person. The complete source code is shown here:
 
   1: using System.Collections.ObjectModel;
   2: using System.ComponentModel;
   3:  
   4: namespace MVVMWithBehaviors
   5: {
   6:    public class PeopleViewModel : INotifyPropertyChanged
   7:    {
   8:       public class Person
   9:       {
  10:          public string Name { get; private set; }
  11:          public Person( string name )
  12:          {
  13:             this.Name = name;
  14:          }
  15:       }
  16:  
  17:       private ObservableCollection<Person> people;
  18:       public ObservableCollection<Person> People
  19:       {
  20:          get { return people; }
  21:          set {  people = value; }
  22:       }
  23:  
  24:       public PeopleViewModel()
  25:       {
  26:          MockGetDataFromTheModel();
  27:       }
  28:  
  29:  
  30:       private void MockGetDataFromTheModel()
  31:       {
  32:  
  33:          string[] firsts = new[] 
  34:             { "Tom", "Dick", "Harry", "Joe", "John", "Ringo" };
  35:          string[] lasts = new[] 
  36:             { "Liberty", "Papa", "Hanselman", "Heuer", "Brown", "Gu" };
  37:  
  38:          var r = new System.Random();
  39:          people = new ObservableCollection<Person>();
  40:          for ( int i = 0; i < 10; i++ )
  41:          {
  42:             people.Add(
  43:                new Person(
  44:                   firsts[ r.Next( firsts.Length ) ]
  45:                   + " "
  46:                   + lasts[ r.Next( lasts.Length ) ] ) );
  47:          }
  48:       }
  49:  
  50:       public event PropertyChangedEventHandler PropertyChanged;
  51:       private void OnPropertyChanged( string propertyName )
  52:       {
  53:          if ( PropertyChanged != null )
  54:          {
  55:             PropertyChanged( this, new PropertyChangedEventArgs( propertyName ) );
  56:          }
  57:       }
  58:    }
  59: }
 

We start by defining a Person (lines 6-15) and then we give the PeopleViewModel class a property People which is an ObservableCollection of Person objects.  The constructor (lines 24-27) calls a method that mocks up getting data from the Model; in this case I just generate ten names on lines 30-48   The final code implements INotifyPropertyChanged, which is not required yet, as the only property we have is an Observable collection.

 

Binding

We are now ready to bind the ListBox inside the View class to the ViewModel.  Add the following two lines to the ListBox declaration in PeopleView.xaml
 
ItemsSource="{Binding People}"
DisplayMemberPath="Name"
and then add this to the constructor in the code behind:
 

DataContext = new PeopleViewModel();

Running the application will now display the data from the ViewModel in the View
 

Behavior

The design of the Silverlight HVP says that when an object changes its state (e.g., the user changes the current item in a list box) the View object will notify the state object of the change. The State object then raises the StateChanged event to which all the View objects have subscribed, and each resets its state.
 
It would be nice to avoid having code in the View to manage the State Change notification; we'd like to bind this as well as the data, thus increasing the overall testability of the project.  Unfortunately, as of now, there is little support for this built into Silverlight (though there is some, using ICommand, with ButtonBase and HyperLink derived classes) 
 
The solution is to be friends with John Papa, who pointed me to the Expression Blend Samples project on CodePlex, which, when installed, provides a library that includes, among other things, the wondrous CallDataMethod, enabling you to trigger a method in your ViewModel based on an event in your view(!)
 
Since I had to spend quite a bit of time figuring out how to make this work, I thought I'd walk through it here. It is very easy, once you know how, but the project doesn't yet provide the necessary instructions. Begin by going to the Expression Blend Samples page and downloading the latest release (which currently is from July 12, 2009 and marked Alpha.  This will put a .msi file on your disk, and running that will install the samples; unfortunately it will do so shockingly quietly, and you'll have no idea what to do next.
 
Here's what you do:  in your project you'll need to add two references. The first is to System.Windows.Interactivity which on my machine is in:
 
c:\Program Files (x86)\Microsoft SDKs\Expression\Blend Preview for .NET 4\Interactivity\Libraries\Silverlight\System.Windows.Interactivity.dll
 
the second is Expression.Samples.Interactivey, which on my machine was in:
 
C:\Program Files (x86)\Microsoft Expression\Blend 3 Samples\Silverlight\Design\Expression.Samples.Interactivity.dll
 

You'll now modify the view class to include the namespaces:
 
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:si="clr-namespace:Expression.Samples.Interactivity;assembly=Expression.Samples.Interactivity"

and finally, you modify the control (the listbox) to add the trigger and behavior

<ListBox Name="Names"
Background="Beige"
Width="200"
Height="250"
HorizontalAlignment="Center"
VerticalAlignment="Center"
ItemsSource="{Binding People}"
DisplayMemberPath="Name">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<si:CallDataMethod Method="HandleSelectionChanged" />
</i:EventTrigger>
</i:Interaction.Triggers>

</ListBox>


The EventTrigger has a property for the EventName; indicating that this trigger will fire when the event SelectionChanged is raised for the ListBox.  The CallDataMethod has a property Method for the name of the method to invoke. Since the ViewModel class is the data context, you don't need to indicated which BindingToMethodsclass supplies the method, any more than you need to indicate which class has the property People to which the ListBox's ItemsSource is binding.

Just add that method to the ViewModel class…

public void HandleSelectionChanged()
{
System.Windows.MessageBox.Show( "Update the state!" );
}

… and start your program. When you change the selection, the method you've bound to will be called.

In the Silverlight HVP this will allow us to bind the event notification to the SelectionChanged event, further decouplit's the control from its data and logic. The technical term for this is "good."

 

Overall Impact of Refactoring for MVVM

While this  is not an exhaustive understanding of MVVM by any means, with these fundamentals, it became obvious how to break up my code, and I found that there was less of it, and it was more intention-revealing.

In fact, the code-behind for my View classes have no code at all except setting the dataContext; and the ViewModel code is short and extremely readable.

 

All in all, I find MVVM well worth the small cognitive startup costs; yielding a very natural separation of concerns, and perhaps equally important, exposing far more of the program to unit tests, and thus driving down the overall time to release.

.

 

 

-----------------------------------

* In 1978 cult leader Jim Jones induced 900 followers to commit "revolutionary suicide" by knowingly drinking cyanide-laced grape Flavor Aid. To the chagrin of General Foods, the cultural memory of the event is that they drank Kool Aid and the expression. To drink the Kool Aid has evolved to mean "to embrace without reservations, the ideas of a strong leader"

Dynamic Blog Posts DynaPosts

Posted: 24 Jan 2010 06:04 AM PST

Blog posts are by their nature static. It is not good form to go back to an existing blog post and update it, but often what I want is to keep everything on one page and have a quick way to notify that the page has been updated.

Starting today, I'll do that on the right hand column. Look for a section titled DynaPosts which will list the dynamic posts, and the last time they were updated.  I'll kick it off with a DynaPost on using VS 2010

The Code Not Taken [Comparing two ways of creating a full-size Popup in Silverlight - then picking the best]

Posted: 28 Jan 2010 10:09 PM PST

When it comes time to display a Popup that overlays the entire Silverlight plug-in, most people do it the same way. Unfortunately, although the typical approach appears correct at first glance (and may even survive a test pass!), there are some problems...( read more )...(read more)

“Badgifying” an ASP.NET page

Posted: 28 Jan 2010 11:05 PM PST

I apologize for the neologism. What I'm going to demonstrate in this post is a technique I prototyped a few months ago to make it very easy to embed an ASP.NET page's content in another page, even if it's using another server technology. This of course works cross-domain. The reason why you would do that is to enable people to embed badges with your contents on their own sites. Examples of such badges can be found in the margin of this blog: there's the ad badge, a Twitter badge, a Facebook badge, an Xbox Live badge, a Zune badge, and there used to be a Flickr badge. There are even full commenting systems that you can include on your blog this way. All those are Flash or JavaScript, and in both cases there's a short JavaScript stub that includes...(read more)

Speaking At Mix10

Posted: 28 Jan 2010 10:59 PM PST

It's that time of year again when a young man's thoughts turn to Las Vegas! Yep, it's another year and another Mix conference (March 15-17, 2010), but this time they've changed locations to Mandalay Bay. It looks like my prediction that the Mix conferences would end at Mix 09 did not pan out. ;) As I did last year , I'll be giving two talks at Mix 10 this year, one of them with the irrepressible Scott Hanselman . What's new in ASP.NET MVC 2 Come see and hear about the latest innovations in ASP.NET MVC 2 and the tooling support in Visual Studio 2008 and 2010. We'll introduce you to a range of productivity (and extensibility) enhancements such as template helpers, model validation, and the new "Areas" feature, which enhances the team development...(read more)

Silverlight Cream for January 28, 2010 -- #789

Posted: 28 Jan 2010 09:49 PM PST

In this Issue: Mark Monster , René Schulte , Damon Serji , Shawn Wildermuth , Rishi , Gavin Wignall ( 2 ), and roboblob . Shoutouts: David Anson reports that Flattery will get you everywhere [Html5Canvas source code now available on CodePlex!] Robbe Morris...( read more )...(read more)

Nice “Quick Hit” Videos about ASP.NET 4 and VS 2010

Posted: 28 Jan 2010 09:12 PM PST

[ In addition to blogging, I am also now using Twitter for quick updates and to share links. Follow me at: twitter.com/scottgu ] I've been working on a series of blog posts the last few months that cover some of the new features coming with .NET 4 and VS 2010. Earlier today someone pointed me at some nice "quick hit" videos that have been published that also provide quick first looks at some of the new features coming with ASP.NET 4 and VS 2010.  These videos aren't an exhaustive list of everything new – but do provide a great way to quickly learn about many of the cool new things coming with the release.  ASP.NET 4 Videos You can learn more about some of the new ASP.NET 4 features by watching these 22 ASP.NET Quick Hit Videos . VS...(read more)

MVVM – It’s Not Kool-Aid*

Posted: 28 Jan 2010 06:15 PM PST

          Okay, first, understand that I'm in the position of running through the streets yelling at folks "c'mere! ya' gotta see this!" and what I'm pointing to is the incredible new invention of… a laptop computer. Something...( read more )...(read more)

PDC video, TechEd Iceland, VS2010, profiling, Silverlight 4

Posted: 28 Jan 2010 02:10 PM PST

(I know I promised this eons ago, so apologies in advance... on the flipside, I'm posting from my vacation in Paris, so hopefully that earns me 1-2 brownie points back.) First, m y PDC slides and the video . This is the same talk that I gave at TechEd...( read more )...(read more)

Learn from the Best in Web Design and Development at MIX10

Posted: 28 Jan 2010 05:20 PM PST

MIX10 favorites Scott Guthrie and Bill Buxton have been announced as keynote speakers at this year's conference. Don't miss the opportunity to hear from these experts and others on UX, design, Windows phone, and much more. Register by February 7th to take advantage of the US$400 discount!

MSDN Webcast: SharePoint Server 2010 (Part 2 of 8): Developing Rich Solutions in Silverlight

Posted: 28 Jan 2010 05:20 PM PST

Discover how to bring Microsoft Silverlight and Microsoft SharePoint Server 2010 together to build and deploy Web parts and field controls, access and update SharePoint content from Silverlight, handle large data sets, and build client-side connections between Silverlight Web parts.

Thursday, January 28, 2010

Capture usage information of a Silverlight application using Google Analytics and a Blend Behavior

Capture usage information of a Silverlight application using Google Analytics and a Blend Behavior


Capture usage information of a Silverlight application using Google Analytics and a Blend Behavior

Posted: 28 Jan 2010 01:15 PM PST

It's already more than a year ago since Tim Heuer published his article on Event tracking in Silverlight. Since that time we've got Silverlight 3 and Silverlight 4 beta. So it's time for a different implementation that can even be used by non-coders....( read more )...(read more)

Handing Events with Care?

Posted: 28 Jan 2010 06:56 AM PST

URL : http://wildermuth.com/downloads/HandledWithCare... The way that events are handled in Silverlight occassionally surprises people. For the uninitiated there are two types of events in Silverlight, direct and routed. Essentially direct events are...( read more )...(read more)

Extensible Output Caching with ASP.NET 4 (VS 2010 and .NET 4.0 Series)

Posted: 27 Jan 2010 11:27 PM PST

[ In addition to blogging, I am also now using Twitter for quick updates and to share links. Follow me at: twitter.com/scottgu ] This is the fourteenth in a series of blog posts I'm doing on the upcoming VS 2010 and .NET 4 release.  Today's post covers some of the output caching extensibility improvements being made to ASP.NET 4.  These can be used by all ASP.NET 4 applications – including those built using both ASP.NET Web Forms and ASP.NET MVC. Output Caching Today ASP.NET 1.0 introduced the concept of output caching, which enables developers to capture and store the generated output of pages, controls, controllers, and HTTP responses in an in-memory cache.  On subsequent web requests, ASP.NET can then serve content faster by...(read more)

Wednesday, January 27, 2010

Announcing the First User Interface (UI) Components for Silverlight 4

Announcing the First User Interface (UI) Components for Silverlight 4


Announcing the First User Interface (UI) Components for Silverlight 4

Posted: 27 Jan 2010 01:05 PM PST

Telerik Corporation , a leading vendor of ASP.NET AJAX, Silverlight, WinForms and WPF controls and components, as well as .NET Reporting, .NET ORM, .NET CMS solutions and Web Application Testing Tools, is excited to announce RadControls for Silverlight...( read more )...(read more)

Silverlight Cream for January 27, 2010 -- #788

Posted: 27 Jan 2010 09:47 AM PST

In this Issue: Richard Waddell , Scott Barnes , Bob Bartholomay , Alex van Beek , Sergey Barskiy , Chris Klug , Microsoft Expression Blog Shoutout: All U.S. MVPs going to the Summit note that Suzanna Moran , my MVP lead, highly suggests the session at...( read more )...(read more)

The Weekly Source Code 48 - DynamicQueryable makes custom LINQ expressions easier

Posted: 27 Jan 2010 01:52 AM PST

NOTE: An alternative title to this post might be: " The Weekly Source Code 48: Making The Weekly Source Code 47 Suck Incrementally Less. " Last week I wrote a post about Dynamic Linq Query Generation in order to solve a kind of meta-programming problem. I had a site that used ASP.NET Dynamic Data and I wanted to do a LINQ query against some data. However, because I was creating a template that didn't know enough at compile time to write a proper LINQ query that could, well, compile, I needed to creating my LINQ dynamically. Be sure to hang in here with me, the awesome happens at the end. I was trying to generate effectively this at runtime Items.Select(row => row.Property).Distinct.OrderBy(colvalue => colvalue) And I succeeded...(read more)

Upcoming Balder release - 0.8.8.6

Posted: 26 Jan 2010 11:00 PM PST

Its been crazy weeks since I decided to pull 0.8.8.5, but it was for the better. The result is that the rendering speed and quality has gone up quite dramatically. The next version of Balder will be 0.8.8.6 and will contain at least the following: - Optimized...( read more )...(read more)

Precompiled Header Files in Visual Studio 2010

Posted: 26 Jan 2010 01:08 PM PST

Hello, this is Andy Rich from the Visual C++ front-end team. Today, I'll be discussing the use of precompiled header files (aka PCH files) in our new intellisense architecture.

Back in May, Boris briefly mentioned an intellisense optimization based on precompiled header technology. This post will elaborate on that comment by providing a glimpse into how Intellisense PCH files (or iPCH files) work. We've all become accustomed to precompiled headers improving build throughput, and now in Visual Studio 2010, we use the same technology to improve intellisense performance in the IDE.

The Problem with "Pre-parses"

 

The VC++ 2010 intellisense engine mimics the command-line compiler by using a translation unit (TU) model to service intellisense requests. A typical translation unit consists of a single source file and the several header files included by that source file (and the headers those headers include, etc.).  The intellisense engine exists to provide users with answers to questions, such as what a particular type is, what the exact signature of a function is (and its overloads), or what variables are available in the current scope beginning with a particular substring.

In order for the intellisense compiler to provide this information, the intellisense engine must initially parse the TU like the command-line compiler, recursively parsing all #include files listed at the top of the source file before parsing the rest of the source file.  Thanks to C++ scoping rules, we know that we can skip all method bodies except the one you might currently be in, but, other than this optimization, the rest of the translation unit must be parsed to give an accurate answer.  We refer to this as the "pre-parse."

Pre-parses are not always required, as users spend much of their time writing code inside of a local scope.  Through careful tracking of user edits, we can say whether or not the user has changed information which requires a new pre-parse.  When this happens, we throw away our old pre-parse and start again.

So, even though you aren't editing header files, they must be continually parsed as part of the pre-parse.  As a translation unit grows in size, these parses require progressively more CPU and memory resources, and will lead to a drop in intellisense performance.  Parsing is slow, and parsing a lot of information (as in a complex translation unit) can be very slow; 3 seconds is not uncommon, and that is simply too long for an intellisense response.

The PCH Model

 

Luckily, there is an optimization developed for command-line compilers that can also be applied to the intellisense compiler: pre-compiled headers (PCHs).  The PCH model presupposes that your translation units mostly share a lot of the same common includes.  You inform the compiler of this set of headers, and it builds a pre-compiled header file.  On subsequent compilations, instead of re-compiling this set of headers, the compiler loads the PCH file and then proceeds to compile the unique portion of your translation unit.

Common Headers

a.cpp

PCH

PCH

Unique includes

b.cpp

Unique includes

c.cpp

Unique includes

There are a few caveats to this model.  First, the "common" portion of your headers must be the first files compiled in each translation unit, and they must be in the same order in all translation units.  Most developers refactor their headers to have a common header file for this purpose; this is what stdafx.h in the Visual C++ project templates is intended for.

Leveraging PCH for the Intellisense Compiler

 

In general, if you have PCH set up for use with the build compiler, the intellisense compiler is able to pick up those PCH options and generate a PCH that can be used.  Because the intellisense compiler uses a different PCH format from the build compiler, separate PCH files are created for the use of the intellisense compiler.  These files are typically stored under your main solution directory, in a subdirectory labeled 'ipch'.  (Future releases may have the command-line and intellisense compilers share these PCHs, but for now, they are separate.)

The intellisense compiler can load these iPCH files to save not only parse time, but memory as well: all translation units that share a common PCH will share the memory for the loaded PCH, further reducing the working set.  So, a properly set-up PCH scheme for your solution can make your intellisense requests execute much more rapidly and reduce memory consumption.

Here are some important things to keep in mind when configuring your project for iPCH:

·         iPCH and build compiler PCH share the same configuration settings (configurable on a per-project or per-file basis through  "Configuration Properties->C/C++->Precompiled Headers").

·         The iPCH should represent the largest set of common headers possible, except for commonly edited headers.

·         All translation units should include the common headers in the same order.  This may be best configured through a single header file that includes all the other headers, with respective .cpp files including only this "master"header file.

·         You can have different iPCH files for different translation units – but only one iPCH file can be used for any given translation unit.

·         The intellisense compiler will not create a iPCH file if there are errors in it – open up the 'error list' window and look for any intellisense errors; eliminate these errors in order to get PCH working.

·         If you feel that an iPCH has somehow become corrupted, you can shut down the IDE and delete the iPCH directory.

 

 

How to read/write the new Visual C++ project properties

Posted: 26 Jan 2010 12:53 PM PST

Visual C++ 2010 introduces several new project properties and item metadata that are not accessible via the traditional VC interfaces.  Andrew Arnott discusses the new way to read and write project properties in Visual C++ 2010 using the IVCRulePropertyStorage interface here.