在 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 顺序
我在 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 顺序