WPF TabControl and Debugging Tricks
My team is currently working on a fairly complex WPF application, and we’re deep into debugging some of the more difficult problems that QA and our users are reporting.
Today’s problem centers around a TabControl with a ListView on every TabItem. Some of the data binding on the ListView was behaving strangely when we switched from one tab to another; it seemed as though our data binding was actually lost entirely when we made a tab switch. The data binding for the first selected tab worked correctly, but when we switched to other tabs it seemed as though some of the first tab’s information was still in place.
When we wrote our code, we had assumed that each TabItem gets its own instance of the ListView. We wanted to verify this, because we were starting to suspect that our assumption was wrong. Coming from the C++ world, we wanted to see the address of the ListView on each tab. But how to do this in C#?
Well, as it turns out, the default implementation of the GetHashCode() method that comes with the Object class will essentially give you the current address of the object instance. In .Net objects can get shuffled around by the garbage collector, so over time they won’t necessarily have the same address. But for quick and dirty debugging purposes for our ListViews, we can at least determine if it’s a different ListView on each TabItem.
Using the Visual Studio Immediate window, or writing a line out to the Console, we can get an object’s default hash code and compare it to another object’s hash code.
As it turns out, because we used a ContentTemplate for our TabItems, the *same* ListView is used on each tab page, rather than a different instance for each TabItem. Once we knew this, we could adjust our code accordingly, and now we are getting the behavior we expected. Bug fixed!
Here’s a Stack Overflow question and answer about the default implementation of the GetHashCode() method.
1 comment
Category:

December 18th, 2010 at 2:20 pm
Anne,
The value returned by GetHashCode() is invariant for the object lifetime. Even when the object moves in memory, due to some GC activity, the internal object ID, and therefore the value returned by GetHashCode will stay the same.