I am using attached behaviours to add the ability to sort a ListView by clicking on a column’s header. The behaviour adds the following handler to handle the user clicking on a GridViewColumnHeader:
listView.AddHandler(GridViewColumnHeader.ClickEvent, new RoutedEventHandler(ColumnHeader_Click));
The handler looks something like this:
static void ColumnHeader_Click(object sender, RoutedEventArgs e)
{
var listView = sender as ListView;
var header = e.OriginalSource as GridViewColumnHeader;
var gridView = ((GridView)(listView.View));
...
}
I just noticed that if the ListView has a scroll bar, and I click on the scroll bar’s ‘shaft’ or scroll arrows (but not thumb!):

(source: microsoft.com)
then the GridViewColumnHeader.ClickEvent is triggered, and my code fails because ‘header’ is now null. Obviously this isn’t an expected behaviour, and now I have to make sure that the OriginalSource is a GridViewColumnHeader.
Why does this happen?
The problem is,
GridViewColumnHeader.ClickEventactually isButtonBase.ClickEvent, which means that the handler you set will be triggered by a user click on any button (or derived: checkbox, datepicker, scrollbar button, etc.) in the ListView, and not only on a column header (which is derived from button).See http://social.msdn.microsoft.com/Forums/en/wpf/thread/3595d153-4faa-4501-9c6f-2f074658e760
The only solution I’ve found is to check that
header != nullbefore doing anything else, to exit the handler when the button that triggered it (e.OriginalSource) was not a column header.Hope this helps…
(PS: also check if
header.Column != null, to avoid an error when the user clicks on the “last extra header”, the empty header on the right of all the “regular” headers…)