Snoop 2.7.0

This post is long overdue. I have written about Snoop for WPF a couple times, and it’s been a while since I gave an update.

Back in September, we published v2.7.0 (release announcement). One of the coolest new features is the ability to drag and drop a cross-hair to the app you want to snoop. You no longer have to wait for the list of applications to refresh.  We added a DataContext tab and various bug fixes.

CropperCapture35

I’ve been spending a bit of my RECESS time lately getting back into contributing to the code base. We have some really cool features in the works — I’ll post again when the next version hits the streets.

Improvements to the WPF Snoop Utility

I made a couple of improvements to the WPF Snoop utility that I posted a while ago.  (as before, this is an update to the original created and posted by Peter Blois, with his permission)

Property Filter ComboBox info now comes from config

After publishing the last version with property filter support, I continue to get suggestions from people using the tool for other properties and groups that should be included.  This is obviously begging for the data to be based on configuration, so I dove in and made it so.

It’s not as straight forward as a simple app.config setting, since the code that displays the property grid and needs to know about those property filter groups is running within the process space of the EXE that you’re snooping.  So you still edit the config file that’s in the directory where have snoop.exe installed, but at runtime, the config is read “remotely” from the snooped EXE.

To add/edit property filters, edit snoop.exe.config.  The layout looks like this:

<PropertyFilters>        <add DisplayName="Layout"         PropertyNames="width,height,actual,margin,padding,canvas,align" />        <add DisplayName="Grid/Dock"         PropertyNames="grid,dock" />        <add DisplayName="Color"         PropertyNames="color,background,foreground,borderbrush,fill,stroke" />        <add DisplayName="ItemsControl"         PropertyNames="items,selected" />        <add DisplayName="Text"        PropertyNames="font,align,trim,wrap" /></PropertyFilters>

 

The comma-separated values in the PropertyNames attribute are split and used as case-insensitive substring searches.

Mouse Wheel Property Editing

I just finished a WPF project where we used Visual Studio 2010, and it required lots of WPF canvas layout.  Normally I would fire up Expression Blend to lay things out exactly where I want them, and be done.  Unfortunately, Blend 3 does not (yet) like VS 2010 project files.  So this made for a very tedious couple months of run-time adjustments of elements.  I would run the app, and use Snoop to adjust Canvas.Left/Top, Margin, Width/Height, etc, each time, typing in a new value, seeing the changes in the app.  UGH.

So that was the motivation for this new feature.  Now when you select a property in the property grid, for fields that support discrete changes to their values, you will see an additional copy of the current value in the right edge of the current value column.  The great thing about this copy of the property’s value is that you can mouse wheel over them to CHANGE THE PROPERTY VALUE!

MouseWheelEditing_4CE25570

There are many data types supported:  the obvious int, double, and boolean; and then maybe not so obvious.  Data types supported:

  • Int32
  • Double

(For the above numeric types, the default is to change the value by 1.  Hold down SHIFT while wheeling to change by 10, hold down CTRL while wheeling to change by 0.1)

  • Boolean
  • Thickness
  • Brush
  • Visibility
  • Horizontal/VerticalAlignment

For the “multi-part” data types (Thickness and Brush), you can change individual parts of the property by mouse-wheeling over just that part.

So this ends up giving me a run-time design experience where I can quickly tweak layout and style without a bunch of text typing / editing.

(Thanks to my co-worker Brad, who tested this version and blew it up when trying to mouse-wheel edit a LinearGradientBrush background.  Types that derive from supported types (i.e. GradientBrush from Brush) that are not supported are listed in the config file and can not be edited with the mouse wheel.  In the case of GradientBrush, you CAN delve into the GradientBrush, to the GradientStops, use the Indexer feature added last time, and then adjust the color or offset of an individual stop at runtime!!)

The Bits

The binaries – one folder for 32-bit and one for 64-bit.

The source code for the solution.

Give it a try!  Hope you like it.

64-bit (x64) Snoop for WPF Development

The popular Snoop tool from Peter Blois has been out for a long time, and I use it almost every day in my WPF development.  However, there has always been something missing:  a native 64-bit version. 

My coworker Joe and I finally decided that it was worth looking into building one.  There were a few tweaks to the code itself to compile in 64-bit, and then some project build directory settings changes … but for the most part, it was pretty straight forward to make. 

So with permission from Peter Blois, I have created and posted a true 64-bit version of Snoop.  Mind you, this is version 1 of Snoop – haven’t yet tried to tackle version 2.  I tend to use v1 in my everyday WPF dev – not having property editing in v2 is a showstopper for me.

Bit Versions

Snoop works its magic by injecting a DLL into the process space of the app you are snooping.  The problem with snooping a 64-bit app with the original snoop is that the injector DLL was always 32-bit, and when Snoop tries to load a 32-bit DLL into the 64-bit target application, you get the invalid image exception. 

To allow snooping either a native 32 or 64-bit target app, I have built both a 32 and 64-bit version of Snoop and its supporting ManagedInjector DLL.   So unfortunately, the only downside of this approach is that you have to keep both versions around, and use the one that’s right for the bit-level of the target app.  (There has already been a request for ONE version of Snoop that will load the appropriate version of the injector DLL, so maybe someday I’ll dig deeper into that.)

Enhancements

While I was in there building Snoop, I decided to throw in a couple other tidbits – either changes to small things that have always bugged me, or small features that I wish the original had. 

  • “ShowAllProperites” ToggleButton is off by default.  I find that more times than not, the properties I want to look at are in the “defaults” set, so this keeps the properties list much shorter.
  • Use a 2nd monitor if present.  My everyday use of Snoop is that I choose the app to snoop, the SnoopUI comes up and I move it over to my 2nd monitor.  I added some code to do this automatically if there’s a 2nd monitor present.
  • Scroll to Selection – when you snoop on an element in your app with CTRL+SHIFT pressed and the element is found in the tree, the selected item is automatically scrolled into view.
  • Custom property filter ComboBox.  In addition to filtering the properties list by text, there is now a ComboBox next it that allows to filter the properties by functionality.  For example, if you choose “Layout”, you see only properties like Width, Height, Margin, etc. that have to do with layout.  Choose ItemsControl for things like ItemsSource, SelectedItem, etc.   This screenshot shows snooping on a ListBox with the custom property filter set to ItemsControl to quickly see everything related to ItemsControls and Selectors.

 BlogSnoop641_3378ECEA

  • Indexer delve.  This is the small TextBox to the right of the Custom Property ComboBox.  If the current property type (that you’ve delved into) is an ICollection, you can type an index value in the TextBox and delve into that item in the collection.  The indexer delve plays along with all the other delves, so you can pop context to get back to where you came from.

Here is the properties window after delving into a collection data type (ListBox.ItemsSource which is ObservableCollection<Person> in this case).

BlogSnoop642_3A2BF66D

After entering a “1” in the Indexer Delve field (updates on text change), you see the Person object at index 1 in the above list.

BlogSnoop643_1A10E9B0

There you have it.   I hope these enhancements, along with a native 64-bit version are helpful in your WPF development!

Here is the zip with both 32-bit and 64-bit folders.  And since the original source was posted, here is the source code for this updated version.