There’s a lot that can be written about hit testing in WPF so I won’t try to cover everything but there are some subtleties that bear mentioning. A common issue that I see people encounter is that fact that the default background for many elements is null and null (at least in terms of hit testing) is treated separately from Transparent. Take the following snippet for example.
An interesting thing to note here is that the TextBlock doesn’t have this issue. So if you were to modify the original source and explicitly set the TextBlock’s Background to {x:Null} or not set it (since it defaults to null) and rerun the original test, you will find that the background of the Grid still changes to yellow when you go over the TextBlock (and not just when you go over the actual rendered text). The reason that this occurs is because the TextBlock explicitly overrides UIElement.HitTestCore and returns true if the specified point is within its rect. There are actually a few other elements that do this as well including ScrollViewer and InkCanvas. For TextBlock I think the main reason is that you probably don’t want the IsMouseOver changing as you move across the text in between characters but this is just a guess.
Another property that affects hit testing in WPF is the IsHitTestVisible. This property determines if the element and its descendants should be hidden from hit testing. I phrased it in this way because if you set IsHitTestVisible to false on the Grid in the sample above, it wouldn’t matter what the IsHitTestVisible state of the descendants is set to since the hit test that is performed to evaluate the IsMouseOver state is going to skip the Grid element and not traverse into its children.
Next time I’ll get to the real reason I started writing about hit testing today – to discuss the methods available for performing hit testing in code.
September 17, 2008 at 1:17 am |
[…] other properties Greg Schecter gives a great intro to Multi-Input Shader Effects Andrew Smith on Hit Testing in WPF Possibly related posts: (automatically generated)Delighted!!Inspiring video about peace – please […]
November 11, 2008 at 11:41 am |
Hi Greg, just noticed your reply on the baml viewer comment-Good to know you’re still around. You’re posts are really helpful! I’ve managed to find myself now in a situation in which I’ve got a ScrollViewer housing a grid housing an ItemsControl and I’d like it to work such that Hit Testing is only apparent on the Items in the ItemsControl because there is content behind (in z-order) the ScrollViewer that I’d like to still hit. So I guess I’m looking to undo the ScrollViewer HitTestCore override that you mention in this post. There’s not too much on this method so my guess at this point is to do something like this in order to mimic the default behavior of a grid:
protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters)
{
Point pt = hitTestParameters.HitPoint;
return new PointHitTestResult((Visual)this.Content, pt);
}
any thoughts?
November 11, 2008 at 5:32 pm |
Hi Yasser. Actually my name is Andrew. 🙂
Unfortunately I don’t think there is a simple way to call the original base. I have one workaround which uses the VisualTreeHelper.HitTest and an anti recursion flag returning null if the mouse is only over the scroll viewer.
public class ScrollViewerEx : ScrollViewer
{
private bool _isHitTesting;
protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters)
{
if (_isHitTesting)
return base.HitTestCore(hitTestParameters);
try
{
_isHitTesting = true;
HitTestResult result = VisualTreeHelper.HitTest(this, hitTestParameters.HitPoint);
return null != result && null != result.VisualHit && this != result.VisualHit
? new PointHitTestResult(this, hitTestParameters.HitPoint)
: null;
}
finally
{
_isHitTesting = false;
}
}
}
November 11, 2008 at 6:53 pm |
Sorry about the name mixup Andrew 🙂 I was looking at that trackback post above that mentioned Greg Schechter and accidentally typed in his name.
Prior to your post, I ended up just overriding the Scrollviewer’s HitTestCore to always return null and that seemed to do the trick. Though I do believe that your implementation is more proper and elegant- Although it does looks like result.VisualHit will always be equal to this ScrollViewerEx instance, I’m wondering under what circumstances would we enter that HitTestCore method and not have the result be == this…
November 11, 2008 at 10:54 pm |
I guess returning null makes sense since that is what an element that wasn’t rendering anything would have done. I made the assumption that the hittest had to return a positive result to recurse into its children.
March 29, 2010 at 9:12 am |
My name is Piter Jankovich. oOnly want to tell, that your blog is really cool
And want to ask you: is this blog your hobby?
P.S. Sorry for my bad english
April 10, 2011 at 1:13 am |
What if you also wanted to change the text in the TextBlock when IsMouseOver is true?
Thanks!
November 4, 2011 at 6:26 am |
ge spacemaker microwave…
[…]Hit Testing in WPF « Andrew Smith[…]…
November 4, 2011 at 4:36 pm |
malaysia taman negara…
[…]Hit Testing in WPF « Andrew Smith[…]…
November 5, 2011 at 12:52 pm |
Gann Trading University…
[…]Hit Testing in WPF « Andrew Smith[…]…
November 9, 2011 at 11:45 pm |
les paul…
[…]Hit Testing in WPF « Andrew Smith[…]…
December 3, 2011 at 4:39 am |
bajar peso…
[…]Hit Testing in WPF « Andrew Smith[…]…
May 2, 2012 at 10:47 pm |
ROFL THIS ARTIVEL IS CRAPOLA
WHAT DUMB NGGR SOB POSTED THIS WORTHLESS PIECE OF CRAP ARTICLE
September 10, 2014 at 9:03 am |
[…] I revised a doubt once Thomas separate out a fake audacity in my uncanny doubt that lead me to learn a genuine reason it wasn't operative in this post. […]
October 18, 2017 at 12:22 am |
https://storify.com
Hit Testing in WPF | Andrew Smith
October 18, 2017 at 10:30 pm |
display driver for windows 8 32 bit
Hit Testing in WPF | Andrew Smith
August 24, 2020 at 7:59 pm |
find out here now Bitniex.com Best Trading on Crypto