Suppressing XAML Debugging Tools

So you know the little black box in your XAML form with links to the debugging tools?  Looks like this:

xaml1

It has links to the Live Visual Tree and the Live Property Explorer, among other things.  They’re useful tools, to be sure, but if I’m not using them, I don’t want to see the little toolbox.  You can minimize it, like this:

xaml2

Now it’s smaller, but it’s still there.  I like a minimalist view of things.  That little black bar annoys me.  It draws the eye.  How to get rid of it?  I asked my friend the internet a few minutes at a time for many days to no avail.  Maybe I wasn’t using the correct search terms.  So I started poking around Visual Studio and I found it here:

xaml3

In retrospect, it seems obvious that it’s in the “Live Visual Tree” tool window (Debug > Windows > Live Visual Tree).  And voila!

xaml4

Aaaaahhhh.  No more little black boxes or bars.  All is right with the world again.

 

Macros! Add ins!

If you’ve long lamented to loss of macros, and more recently the loss of add-ins in Visual Studio, now you can have them both back in Visual Studio 2015.  Sort of.

With the Visual Commander extension, you can record and playback macros.  If you have some fairly simple add-in code and haven’t been willing to spend the time to convert it to an extension, you can use it practically intact.

I can once again save all files, close all files, open the Start window, and collapse all nodes in the Solution Explorer with a single mouse click.  yay!

Organizing Bookmarks

If your “Bookmarks” window just says Bookmark1, Bookmark2, etc., you’re not getting the full potential out of your bookmarks.

  • You can right-click and change the name of a bookmark.
  • You can create folders to group bookmarks together.
  • You can drag & drop to reorder bookmarks.

Put all these features together, and your bookmarks window is capable of conveying so much more information.  For example, the image below shows me the list of bookmarks, in order, associate with Pasting an A.

bookmarks

Multiple TFS Servers

I’ve currently got two TFS servers running parallel and sometimes when I switch from one to the other I get scary messages:

2016-10-28_9-11-30

2016-10-28_9-11-41.png

Not to worry.  Don’t panic.  It’s only that the cached TFS files have gotten corrupted.  In my case I’m switching between TFS 2012 and TFS 2015 and for some reason switching from 2015 back to 2012 makes Visual Studio unhappy.

The cache is located at C:\Users{username}\AppData\Local\Microsoft\Team Foundation\5.0\Cache.  The generally recommended solution is to delete the entire contents of that directory.  Caution: as you might imagine, there’s information in there that TFS and Visual Studio use, like the list of checked out files you’ve selected for exclusion in the Pending Changes window.

Also of note, there may be more than one cache directory.  In my case, I have three of them for whatever reason (4.0, 5.0, 6.0).  Turns out it’s my 5.0 that’s in use.  No idea what the other ones are.

Double Event Execution in global.asax

The native events in global.asax will autowireup no matter what you do. If you explicitly handle the event, it will execute from the autowireup and from the Handles statement. Hilarity will ensue.

So to be clear, this is bad:

Private Sub Application_PreRequestHandlerExecute(ByVal sender As Object, ByVal e As EventArgs) Handles Me.PreRequestHandlerExecute
End Sub

This is good:

Private Sub Application_PreRequestHandlerExecute(ByVal sender As Object, ByVal e As EventArgs)
End Sub

Singleton Pattern

If you don’t want to use static methods for whatever reason, you can still gain the benefits of static methods by using the singleton pattern. The resultant behavior is that the entire object acts like it’s static.

using System.Diagnostics;

namespace Company.Product
{
    internal class Singleton
    {
        // We make the constructor private so the class
        // can't be externally instantiated.
        private Singleton(){}

        static private Singleton _localStaticInstance;

        // We add a static method that will return
        // the instance object that's stored internally.
        static public Singleton Instance
        {
            get
            {
                if (_localStaticInstance == null)
                {
                    _localStaticInstance = new Singleton();
                }
                return _localStaticInstance;
            }
        }

        public string GetWorld()
        {
            return "Hello!";
        }
    }

    internal class Test
    {
        public void Exercise()
        {
            // The static instance method actually returns an instantiated object.
            // It's instantiated internally and every call to the static method returns
            // the same instance every time.  Caching is fun!
            Debug.Print(Singleton.Instance.GetWorld());

            // Or if you don't want to type 'Singleton.Instance' every time,
            // you can store a reference locally for less typing.
            var singleton = Singleton.Instance;
            Debug.Print(singleton.GetWorld());
            Debug.Print(singleton.GetWorld());
            Debug.Print(singleton.GetWorld());
        }
    }
}

Comparing Dates

Prior to SQL Server 2008, there’s no such thing as a date. There is only datetime. Because of the time, you can’t simply use a WHERE clause like this:

WHERE (@MyFirstDate = getdate())

They’ll never match! Unless it’s actually exactly midnight.

It gets even more unpredictable if you’re making relative comparisions:

WHERE (@MyFirstDate > '3/2/2015')

If @MyFirstDate is ‘3/2/2015 3:27 PM’, that WHERE clause will actually return True. If the date parts are the same, you’re actually asking if 3:27 PM > 12:00 AM.

To reduce the uncertainty, you should always use DATEDIFF. If you’re comparing just dates, you can specify to compare based on days where the difference in days is zero.

WHERE (DATEDIFF(d, @MyFirstDate, getdate()) = 0)

Luckily, in 2008 they introduced the date and time data types. Now you can store just the part you need and avoid all this silliness.

Here’s some light reading for other date and time functions: Date and Time Data Types and Functions