问题描述
我继承了一个程序,该程序使用命中测试来处理针对画布上一堆绘图的鼠标事件。在某些情况下,我的 HitTestResultCallBack 不再被调用。
这里是调用 HitTest 的地方(从 mousemove 事件调用):-
internal void HitTest(System.Windows.Input.MouseEventArgs e)
{
m_visualTrackerHit = m_visualTrackerHit2 = null;
Point location = e.GetPosition(this);
Geometry g = new RectangleGeometry(new Rect(location.X - m_connectdistance,location.Y - m_connectdistance,m_connectdistanceX2,m_connectdistanceX2));
HitTestParameters parameters = new GeometryHitTestParameters(g);
HitTestResultCallback callback = new HitTestResultCallback(this.HitTestCallback);
System.Diagnostics.Debug.Print("About to Hit Test");
VisualTreeHelper.HitTest(this,null,callback,parameters);
}
这是我的回调函数:-
private HitTestResultBehavior HitTestCallback(HitTestResult result)
{
System.Diagnostics.Debug.Print("HitTestCallBack");
DrawingVisual visual = result.VisualHit as DrawingVisual;
if (visual != null)
{
VisualTracker visualTracker = visual.GetValue(FrameworkElement.TagProperty) as VisualTracker;
if (visualTracker != null && visualTracker.Type != VisualType.Selection && visualTracker.Type != VisualType.Ignore)
{
if (m_visualTrackerHit == null || visualTracker.Type < m_visualTrackerHit.Type)
{
m_visualTrackerHit = visualTracker;
}
}
}
return HitTestResultBehavior.Continue;
}
这一切都很好,直到我采取了一个特定的、显然不相关的行动。 (在这种情况下,每个图形都代表一个具有各种属性的“组件”。将属性设置为无效值会导致问题,但这都是领域内容,几乎可以肯定与我的问题无关)。一旦采取该行动,回调方法就会停止被调用。备注不仅仅是因为绘图的属性发生了变化,回调停止被调用为画布和它上的所有对象。
我已经跟踪了动作的代码路径,在那里看不到任何明显的东西,但它非常复杂,我很可能遗漏了一些东西,所以我想从另一个方向来解决这个问题。回调不会被调用的可能原因是什么。
我已检查以下内容:-
正在使用正确的值定义 RectangleGeometry,因此它应该表明与绘图发生冲突
任何地方都没有将 IsHitTestVisible 设置为 false。
有什么建议吗?
解决方法
我想回到这个问题上,因为我终于找到了答案——或者至少是其中的一部分。在组件上设置为无效值的属性导致该组件的 draw 方法出现除以零错误。这意味着该组件并未重绘,而是保留了它的旧绘图,这意味着发生错误并不明显。
我对此进行了一些测试,绘制到画布上的任何未处理的错误似乎都会导致不再为该画布上的任何内容调用 hitTestCallback。我不知道为什么会这样,但此时我很容易解决,因为我可以防止除以零异常
,使用 Snoop 调试您的程序:
- 确定工作案例的事件路径
- 确定非工作案例的事件路径
- 一旦你查明原因,你就可以想出解决办法