在 silverlight 中选择和取消选择重叠图形

Selecting and Deselecting overlapping graphics in silverlight

我在 canvas 上放置了一条线(我们称它为第 1 线),并为其附加了鼠标进入、鼠标离开、鼠标抬起和鼠标按下事件。然后创建附加相同事件的另一行(第 2 行)。选择任何一行时,所有事件都会完美运行。 出于某种原因,当创建的第一行被拖动并释放到创建的第二行时,该行不会在 canvas 上释放,但它仍然粘在鼠标指针上,直到再次单击第二行线。当最早创建的行被拖动到较新的行上而不是相反时会发生此问题(当第 1 行被拖动并在第 2 行上释放但反之亦然,或者第 1 行超过第 2 和第 3 行,第 2 行超过第 3 行时会出现问题等等 我不知道什么代码可能有助于解决这个问题,有没有人有任何建议或者可能遇到过类似的问题?

观察到的行为的原因很容易推断:

Panel 中的所有元素都有一个隐含的 z 顺序,当没有为 en 元素指定 ZIndex 属性 时,该顺序将生效。较早添加的元素的 z 顺序低于较晚添加的元素(xaml 标记是从上到下解析的,较早出现的元素会较早添加)。

现在,如果您开始四处移动元素并且两个元素重叠,z 顺序仍然有效。因此,您之前添加的行将被视为在物理上位于另一行下方,并且所有鼠标事件都将转到 z 顺序中的最顶层行。因此,您移动的元素不会收到 MouseUp 事件,并且它仍然粘在鼠标指针上,直到您将鼠标从重叠区域移开并再次释放鼠标。

我能想到几个办法解决:

可能最简单的方法就是在 select 元素上设置一个明确的 ZIndex ,当你四处移动它时,它总是在所有其他元素之上,当你在任何地方释放它时,你可以再次清除 ZIndex。一些示例代码给你一个想法:

private void OnElementSelected()
{
    // todo: maybe we need to store the previous zindex value and re-assign it later
    // to prevent it from getting lost
    Canvas.SetZIndex(this, Int32.MaxValue);
}

private void OnElementReleased()
{
    this.ClearValue(Canvas.ZIndexProperty);
    // todo: maybe re-assign stored z-index value
}

另一种解决方案是在整个 Canvas 上放置一个透明的 MouseEventObserver,它会在您 select 一个元素时立即激活,这样元素的顺序就无关紧要了。

编辑

关于 Canvas.ZIndex 附加 属性 的一个好事实(许多开发者可能没有意识到):它适用于所有面板类型,而不仅仅是 Canvas。因此,您甚至可以使用 Canvas.ZIndex.

指定 Grid 中元素的 z 顺序