Visual Studio 2010 Tooltip Assassin

March 29, 2013

I don’t know about you, but the Visual Studio 2010 XAML and C# editor tooltips don’t provide much value.  When presenting they are a distraction. When I collapse a region of XAML and the mouse wonders over the collapsed region I get this enormous tooltip painted over the XAML I’m looking at.

I finally decided to put a stop to this and code tooltip free.

I found this elegant solution provided by Noah Richards that he posted on github:  DisableQuickInfo.

I made one modification to his code by adding a second ContentType attribute to include XAML.

You can download the vsix file below and install or simply use this code to build the project yourself.  If you have Visual Studio 2012 you’ll need to build it yourself.

After installing you view the extensions information in Visual Studio’s Extension Manager.



namespace QuickInfoAssassin {
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.Composition;
    using Microsoft.VisualStudio.Language.Intellisense;
    using Microsoft.VisualStudio.Text;
    using Microsoft.VisualStudio.Utilities;

    //Many thanks to Noah Richards and his DisableQuickInfo extension

    [Name("Quick Info Assassin")]
    [Order(Before = "Default Quick Info Presenter")]
    internal class QuickInfoAssassinProvider : IQuickInfoSourceProvider {
        public IQuickInfoSource TryCreateQuickInfoSource(ITextBuffer textBuffer) {
            return new CancelingQuickInfoSource();

    internal class CancelingQuickInfoSource : IQuickInfoSource {
        Boolean _isDisposed;

        public void AugmentQuickInfoSession(
            IQuickInfoSession session, IList<Object> quickInfoContent,
            out ITrackingSpan applicableToSpan) {
            // Dismiss the session immediately.
            applicableToSpan = null;

        public void Dispose() {
            if (!_isDisposed) {
                _isDisposed = true;

If you are not familiar with creating Visual Studio Editor Extensions MSDN provides a number of walkthroughs to get you going.  I used this one: Walkthrough: Displaying QuickInfo Tooltips.

You’ll need the Visual Studio SP1 SDK to create the project that can be found here.


After downloading change the extension from .vsix.DOC to .vsix. This is a requirement of WordPress. You will also need to Unblock the file using the file properties dialog in Windows Explorer.

Download (QuickInfoAssassin.vsix (40 KB))

Have a great tooltip free day,

Just a grain of sand on the worlds beaches.

Speaking at Boise Code Camp March 16, 2013

February 25, 2013

I’m very much looking forward to the 16 March, 2013 Boise Code Camp. Speakers have signed up for some very cool and informative talks.

I’ve signed up for two sessions myself. The abstracts can be viewed here.

  • An Approach to Real World Application Data Caching
  • Using Mole for Debugging Visual Studio 2010 and 2012 Applications

In addition, I’ll release Ocean 3 as part of the associated session source code.

Have a great day,

Just a grain of sand on the worlds beaches.

Change and Deleted Item Tracking within the Infragistics DataGrid

July 2, 2012

Now that I’m back developing production Line of Business (LOB) applications again, I wanted to share some techniques and challenges that I’ve overcome in our WPF UI.

Our company uses the Infragistics NetAdvantage for WPF product for our WPF UI. We have been very happy with the product, support response and updates. Currently we use the XamRibbon, and XamOutlookBar in our Prism shell; the XamDataChart in our Dashboard; and XamDataGrid in our data entry forms. Our application is in its infancy and as new requirements, features and capabilities are added we will be using more of the controls in the NetAdvantage for WPF full featured suite.


For my first post, I thought I would cover an aspect of using the XamDataGrid (all data grids really) that is foundational to LOB applications.

What I’m referring to is tracking the users edits (inserts, updates and deletes) while working in a data grid and then providing the capability to utilize the same database connection to perform the updates, and optionally perform the updates as an atomic transaction.

There are use cases when a user changes data in a data grid, that those changes are immediately reflected back to the database.

Our scenario is one where the design requires that the user be able to make their edits and then commit all the changes all at once. An example of this would be a master-detail use case, when child rows are associated with a master record, e.g. customers, orders, order detail.

In this example, all other development concerns such as data validation, concurrency, actually reading from or writing to a database are not part of the example code; this enables the reader to focus on one technique for tracking inserts, updates, and deletes.

XamDataGrid Requirement

The Infragistics XamDataGrid requires that the data source implement IBindingList in order for the data grid to support adding rows.

Yes, there are techniques for dynamically adding data to your data source without having to do this, but I wanted to allow the data grid to perform its work in a natural way so our data source is derives from BindingList<T>.

Tracking Inserts, Updates and Deletes

When the user deletes a row in the XamDataGrid, the row is removed from the collection and is not longer visible in the UI.

This is where the below ChangeTrackingBindingList<T> comes into play. This class keeps track of the deleted rows by adding a deleted row to an internal collection and then exposing a method (GetDeletedItems) to return those deleted rows when required. If you look below, you’ll see I’ve overridden the RemoveItem method; the implementation adds the deleted row to the internal collection of deleted rows.

It also exposes a method (GetChangedItems) to return only those non-deleted rows that have been inserted or updated.

namespace GridEditing.Infrastructure {
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;

    /// <summary>
    /// Represents the ChangeTrackingBindingList that tracks changes and deleted items.
    /// </summary>
    /// <typeparam name="T">
    /// T: The type of object to provide change tracking binding list services for.
    /// </typeparam>
    public class ChangeTrackingBindingList<T> : BindingList<T> where T : ITrackDirtyEntity {

        IList<T> _deletedItems = new List<T>();

        /// <summary>
        /// Initializes a new instance of the <see cref="ChangeTrackingBindingList{T}"/> class.
        /// </summary>
        public ChangeTrackingBindingList() {

        /// <summary>
        /// Initializes a new instance of the <see cref="ChangeTrackingBindingList{T}"/> class.
        /// </summary>
        /// <param name="list">The list.</param>
        public ChangeTrackingBindingList(IList<T> list)
            : base(list) {

        /// <summary>
        /// Gets all items in the collection.
        /// </summary>
        /// <returns>
        ///   <see cref="IEnumerable{T}"/> that contains all items from this collection; 
        ///   includes deleted and non-deleted items.
        /// </returns>
        public IEnumerable<T> GetAllItems() {
            return this.Union(_deletedItems).ToList();

        /// <summary>
        /// Gets items that have been changed in the collection.
        /// </summary>
        /// <returns>
        ///   <see cref="IEnumerable{T}"/> that contains items that have been changed; 
        ///   does not include deleted items.
        /// </returns>
        public IEnumerable<T> GetChangedItems() {
            return this.Where(i => i.IsDirty).ToList();

        /// <summary>
        /// Gets the deleted items.
        /// </summary>
        /// <returns>
        ///   <see cref="IEnumerable{T}"/> that contains all items deleted from this collection.
        /// </returns>
        public IEnumerable<T> GetDeletedItems() {
            return _deletedItems;

        /// <summary>
        /// Clears the items.
        /// </summary>
        protected override void ClearItems() {
            _deletedItems = new List<T>();

        /// <summary>
        /// Sets the item's MarkedAsDeleted property to <c>true</c>. 
        /// Adds the item to the DeletedItems collection. Removes item from list.
        /// </summary>
        /// <param name="index">The index.</param>
        protected override void RemoveItem(Int32 index) {
            var item = this[index];

Consuming the ChangeTrackingBindingList<T>

The below MainWindowViewModel exposes the Customers collection. The collection is initialized and customers inserted in the constructor. (please do not populate your collections in your constructors, this is demo-only code)

You’ll notice that after loading the customers, I loop through the collection and set the IsDirty property to false. Your base class for your entity objects should handle this for you, so that when an object is populated from a database, the object is returned from the service layer in a non-dirty state to provide accurate tracking in the UI layer. The below example is over simplified on purpose to show how the view model will process the data once the user saves their changes.

The most important method below is the SaveExecute method that is invoked when the user clicks the Save button. The CanSaveExecute method determines if the collection has been changed or not. Any change to the collection will cause the Save button to be enabled.

Please Note: the code in the SaveExecute method would 99.9999% of the time actually be executing in a service layer. The service layer method would receive the ChangeTrackBindingList<T> as an argument and would use a data layer to process the changes.

Within the SaveExecute method we can see the workflow:

  • Deleted items are removed from the database.
  • Then the inserted or updated items are committed to the database.
  • The view model would then reload the inserted and changed data into the data grid. This reloading refreshing the timestamps that play the role in concurrency and identity columns are populated after an item is inserted and reloaded from the database.
namespace GridEditing {
  using System;
  using System.Diagnostics;
  using System.Linq;
  using System.Windows.Input;
  using GridEditing.Infrastructure;
  using GridEditing.Model;

  public class MainWindowViewModel : ObservableObject {
    ChangeTrackingBindingList<Customer> _customers;
    ICommand _saveCommand;
    Boolean _customersDirty;

    public ChangeTrackingBindingList<Customer> Customers {
      get { return _customers; }
      set {
        _customers = value;

    public ICommand SaveCommand {
      get { return _saveCommand ?? (_saveCommand = new RelayCommand(SaveExecute, CanSaveExecute)); }

    public MainWindowViewModel() {
      // load from the service layer
      var list = new ChangeTrackingBindingList<Customer>();
      list.Add(new Customer { FirstName = "Josh", LastName = "Smith", Id = 1 });
      list.Add(new Customer { FirstName = "Sacha", LastName = "Barber", Id = 2 });
      list.Add(new Customer { FirstName = "Brian", LastName = "Lagunas", Id = 3 });
      list.Add(new Customer { FirstName = "Karl", LastName = "Shifflett", Id = 4 });
      foreach (var customer in list) {
        customer.IsDirty = false;
      this.Customers = list;
      this.Customers.ListChanged += (s, e) => _customersDirty = true;

    Boolean CanSaveExecute() {
      return _customersDirty;

    void SaveExecute() {
      // call the service layer, passing the DeleteMarkingBindingList<Customer>
      // the service layer will loop through each item, and either insert it, update it, delete it, 
      // or discard.
      // this is demo code only, but demonstrates the workflow

      foreach (var customer in this.Customers.GetDeletedItems()) {
        // if the Id property is zero then the service layer does not have to do anything
        // if the Id property is greater than zero, the service layer will delete the item.
        // simulate removing from the data base
          String.Format("Customer deleted: {0} {1}", customer.FirstName, customer.LastName));

      foreach (var customer in this.Customers.GetChangedItems()) {
        if (customer.Id == 0) {
          // perform insert in service layer
          customer.Id = this.Customers.Max(c => c.Id) + 1;
          // simulate inserting into the data base
            String.Format("Customer inserted: {0} {1}", customer.FirstName, customer.LastName));
        } else {
          // perform update in service layer
          // simulate updating the data base
            String.Format("Customer updated: {0} {1}", customer.FirstName, customer.LastName));

      // reload the updated records from the database
      // simulate getting all records from the database

      _customersDirty = false;

Running the Application

When the application is initially spun up, the Save button will be disabled since no inserts, updates or deletes have taken place.


After a row has been inserted, the Save button is enabled.


To the initial data, the following changes have been made.


When the Save button is clicked, notice the Debug output window. Each of the requested operations are performed; these operations are easily driven by the ChangeTrackingBindingList<T>.


After the Save is completed, the UI will be updated as below, the Id field has been populated and the Save button is disabled again.


UI XAML – XamDataGrid Tips

The Infragistics XamDataGrid really makes it easy for developers to deliver a full-featured data grid editing experience. This example does not even scratch the surface of the many capabilities of the data grid. In future posts I’ll demonstrate some real-world scenarios with respect to the XamDataGrid’s UI capabilities, for now, let’s stick with tracking the users edits and updating the database.


1.  By default the XamDataGrid will set string properties to null if the user enters a blank or empty string in the data grid. This is not the behavior I want, instead I need an empty string. This is accomplished using a no-op converter.

Infragistics has made applying the no-op converter a snap by setting ValueToTextConverter property on the XamTextEditor using a style as I’ve done below. In the XamDataGridNullStringPreventionConverter’s Convert and ConvertBack methods I simply return value. The causes the XamDataGrid to set string properties to an empty string instead of the null value.

2.  Take a look down at the XamDataGrid.FieldSettings, you’ll notice CellClickAction has been set to EnterEditModeIfAllowed. The user no longer has to double click a cell to get into edit mode, simply clicking the cell, will put the cell in edit mode.

3.  Making an Id field read-only is straightforward. Have a look at the Id field in the XamDataGrid’s FieldLayout. By setting Id columns FieldSettings.AllowEdit to false, the cells are read-only.

    Title="Data Grid Editing and Deleting" 
    <local:MainWindowViewModel />
      x:Key="XamDataGridNullStringPreventionConverter" />
      <RowDefinition Height="Auto" />
      <RowDefinition Height="*" />
      <RowDefinition Height="Auto" />
    <TextBlock Text="Infragistics Data Grid Editing and Deleting" Margin="11" FontSize="18" />
      Grid.Row="1" Margin="11" 
      DataSource="{Binding Path=Customers}" IsNestedDataDisplayEnabled="False">
        <Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}" >
          <Setter Property="Margin" Value="0" />
        <!--this style is required to prevent null strings from being sent to the model-->
        <Style TargetType="{x:Type igEditors:XamTextEditor}" >
            Value="{StaticResource XamDataGridNullStringPreventionConverter}" />
        <igDP:FieldSettings CellClickAction="EnterEditModeIfAllowed" />
                    ExpansionIndicatorDisplayMode="Never" />
            <igDP:FieldSortDescription FieldName="Id" Direction="Ascending" />
          <igDP:Field Name="Id">
              <igDP:FieldSettings AllowEdit="False" />
          <igDP:Field Name="FirstName" Width="200" />
          <igDP:Field Name="LastName" Width="200" />

      Width="65" Margin="7" Grid.Row="2" Content="Save" 
      Command="{Binding Path=SaveCommand}" HorizontalAlignment="Right"/>



After downloading change the extension from .zip.DOC to .zip. This is a requirement of WordPress.

Download Demo Application (25K)


To run the demo application, you’ll need to get the Infragistics NetAdvantage for WPF. A demo version is available here.


There are business frameworks like CSLA that have trackable objects and handle the above scenarios I’ve shown. Currently, I prefer to the simplest solution possible and use the above for tracking user changes within the XamDataGrid.

You can see the amount of very simple code to enable this scenario is small, easy to understand and implement.

Have a great day,

Just a grain of sand on the worlds beaches.

Simplifying Prism WPF Navigation – Synchronous Navigation Confirmation

September 5, 2011

Microsoft patterns & practices Prism 4 library and guidance gives WPF and Silverlight developers a very solid foundation for creating business applications. Adopting Prism patterns and library features guides the developer towards creating applications that: can evolve over time, are not tightly coupled, can be independently developed across a large team, are Blendable, and testable.

New to Prism 4 was the Navigation API’s. The use of the Navigation API’s greatly simplifies application development because the Navigation API takes over the responsibility of object creation and siting objects in the target region.

The Prism library is designed to support applications that can target WPF and Silverlight with good code reuse. While not all developers need this capability, a lot of thought and design decisions were made to fully support this scenario.

One API that took this capability into account while being designed is the Navigation API; specifically the confirmation of a navigation request. Objects that implement IConfirmNavigationRequest have the option to veto a navigation request. In order to support the limitation that Silverlight does not allow blocking dialog boxes, the IConfirmNavigationRequest.ConfirmNavigationRequest method had to be written so that Silverlight objects could participate in vetoing a navigation request without a blocking dialog.

Without going into all the details (you can read them here), objects that implement IConfirmNavigationRequest are required to invoke the callback in the ConfirmNavigationRequest method arguments. Objects are free to implement any vetoing code they want as long as the callback is invoked.  In practice the navigation request is halted until the callback is invoked. This design enables Silverlight developers to implement a variety UI solutions for prompting the user, for example the Prism Interaction Request.

I’ve found that I’m my WPF development that I had to jump through the above hoops just to have navigation confirmation, when in fact WPF has out of the box support for modal, UI blocking dialogs. In an effort to simplify my WPF applications I’ve created a replacement for the Prism RegionNavigationService that allows for synchronous navigation confirmation.

The implementation is very straightforward and only requires that you add one class and one interface to the Prism library and recompile it.

The RegionNavigationSynchronousService is the replacement for the stock RegionNavigationService. This class uses the new synchronous (blocking) navigation confirmation interface IConfirmNavigationRequestSynchronous, listed below.

public interface IConfirmNavigationRequestSynchronous : INavigationAware
    /// <summary>
    /// Determines whether this instance approves being navigated away from.
    /// </summary>
    /// <param name="navigationContext">The navigation context.</param>
    Boolean ConfirmNavigationRequestSynchronous(NavigationContext navigationContext);

By default, Prism automatically registers the RegionNavigationService in the container as part of the bootstrapping pipeline. However, we want to use the WPF friendly synchronous confirmation service, RegionNavigationSynchronousService.

All that is required is to override the ConfigureContainer method in your bootstrapper and register RegionNavigationSynchronousService as I’ve done below.

namespace TestBench {
    using System.Windows;
    using Microsoft.Practices.Prism.Modularity;
    using Microsoft.Practices.Prism.Regions;
    using Microsoft.Practices.Prism.UnityExtensions;
    using Microsoft.Practices.Unity;
    using TestBench.Customers;

    class Bootstrapper : UnityBootstrapper {
        protected override IModuleCatalog CreateModuleCatalog() {
            var catalog = new ModuleCatalog();
            catalog.AddModule(typeof (CustomersModule));
            return catalog;

        protected override DependencyObject CreateShell() {
            var shell = this.Container.Resolve<ShellView>();
            Application.Current.MainWindow = shell;
            return shell;

        protected override void ConfigureContainer() {

            // register the new navigation service that uses synchronous navigation 
            // confirmation instead of the async confirmation.

Below is a very simple implementation.

PLEASE do not put MessageBox code in your view models!  This is for demo purposes only and to keep the code simple.  Please use a dialog service that abstracts the UI dialog away from the view model.

The below code is from the included download and is in the CustomerMaintenanceViewModel. The below ConfirmNavigation property allows the demo to confirm or not but is not part of the Navigation API. This method returns true or false to continue the navigation request or not.

public Boolean ConfirmNavigationRequestSynchronous(NavigationContext navigationContext) {
    if (this.ConfirmNavigation) {
        if (MessageBox.Show("Close form and navigate?", "Confirm Navigation", 
            MessageBoxButton.OKCancel, MessageBoxImage.Question) == MessageBoxResult.OK) {
            return true;
        return false;
    return true;

Demo Application


Very simple Prism application that demonstrates confirming navigation requests and region lifetime. The status bar indicates the views in the ContentRegion on the right.  As you open or close views their name will be displayed; for the Customers, the customer number will be displayed.

Crack the code open, you’ll have this down in a few minutes.


As always, don’t forget to “Unblock” the zip file after downloading from the Internet before you unzip it.

Synchronous Prism Navigation (177KB)

The download includes a sample Prism solution that your can run without modifying your Prism library code.  I’ve included a \Lib folder in the solution with pre-built, modified Prism library code.

I’ve also included two files in the \PrismSource folder that you can add to your Prism library. Simply copy these two files into the below folder and recompile Prism. You now have the option to use a simpler navigation confirmation API in your WPF projects. 

This only works in WPF and NOT Silverlight.  If you have the requirement to share code between WPF and Silverlight this will not work because Silverlight requires the navigation confirmation to be async.


Have a great day,

Just a grain of sand on the worlds beaches.

Windows Phone 7 – Seattle Silverlight User Group Meeting Code

August 4, 2011

On 8/3/2011 I did a presentation for the Seattle Silverlight Users Group called, “A Slice of Mango – Data Forms.”

This presentation was on data forms for Windows Phone 7.

The MangoForms demo application consists of a series of forms that each focus on a single aspect of a form such as, scrollability, type mismatch exceptions, validation, ICommands, IDataErrorInfo, sample data, design-time tooling, MVVM, etc.

I’ll try and publish a few videos that capture the teaching presented at the meeting.


You can download the code and deck from my Sky Drive here.

Note:  The deck is in the folder SiliconValleyCodeCamp and is for the Application Life Cycle training.  There is no deck for this presentation, just code.

Have a great day,

Just a grain of sand on the worlds beaches.

Boise Prism, Unity, WPF, MVVM Code and Decks

June 29, 2011

Everyone had a great time in Boise this week with developers from the United Kingdom and all over the United States.  WPF is alive and well and being used in corporate development along with Prism!


C# early version of Ocean.

  • Data Binding
  • M-V-VM
  • Commands in M-V-VM
  • Dialogs in M-V-VM
  • Data Validation
  • M-V-VM Tips & Tricks
  • Unit Testing & Moq
  • Introduction to Prism
  • Unity and Dependency Injection
  • Shell and Bootstrapping
  • Modules
  • Regions
  • Events
  • Navigation


The download includes PowerPoint decks for most of the sessions and source for all sessions.  Also included is an  Extras folder with goodies.


You can download the code and decks from my Sky Drive here.

Have a great day,

Just a grain of sand on the worlds beaches.

Mole v 1.3 for Visual Studio 2010 Released

June 20, 2011

Mole 2010 v1.3 contains a lot of enhancements made in response to customer feedback. These range from simple bug fixes to making existing features more powerful.

Developers leveraging Prism will be happy to find enhanced support for exploring objects from the Prism and Unity frameworks.

Several fixes will make our large user base in Germany quite happy, including the ability to use a list separator, other than a comma, in exported CSV files.

Mole v1.3 Enhancements

  • Fixed bug where Mole would not close properly when computer has a touch-enabled screen (worked around a WPF issue).
  • Enabled viewing and drilling into more collection types. Mole 2010 now supports drilling into any IEnumerable object.
  • Both the Key and Value properties of a DictionaryEntry object are now shown in the MoloScope’s Value column.
  • Collection items for NameValueCollection now show the keys and values in the MoloScope.
  • Improved support for working with Prism and Unity applications (support for drilling into the RegionManager and Unity container collections).
  • Enabled drilling into objects with only non-public fields.
  • Exporting collection data to CSV now uses the list separator defined by your system locale, instead of always using a comma.
  • The Options dialog allows you to specify a list separator to use in the CSV files, if necessary.
  • MoloScope column widths are no longer set to incorrect large values when running on a system with the German locale.
  • Snapshot rendering of Windows Forms controls has been modified to properly handle some edge cases.

Current Registered Users

Current registered users of Mole can download this updated version and install the new version over old one.

Demo Version Available

If you are interested in trying out Mole 2010 before buying it, visit the Molosoft Demo page to get the latest release of the trial version. The trial version includes the new features and fixes listed on this page.

Learn About Mole

To learn about the Visual Studio 2010 Debugger Visualizer Mole and how this debugging tool can help you when debugging applications in Visual Studio 2010, please visit


We welcome and appreciate your feedback on Mole!

Have a great day,

Just a grain of sand on the worlds beaches.


Get every new post delivered to your Inbox.

Join 255 other followers