2010-11-12 81 views
0

基本上我为Silverlight创建了一个“Adorner”类,它允许用户移动,缩放和旋转它所装饰的任何对象。这种方式的工作原理是Adorner监视它的子元素上的任何鼠标事件并作出相应的响应。如何在Silverlight中的Canvas上“伪造”鼠标单击事件?

这适用于椭圆和矩形等简单元素。但我有一个自定义元素,其中包含一个图像和一个标签内的画布。

我的问题是这样的。我希望用户能够独立地从图像中移动标签,但只将偏移量保持为偏移量(因此,为什么我不只是让它们分别添加图像和标签)。这意味着标签需要使用Canvas.Left和Canvas.Top属性。但是,每当我添加这些标签时,标签就变得无法点击......即当点击标签时,该元素不再识别点击,但它仍然响应用户单击图像。

我认为这与Canvas元素没有自动布局控制的方式有关。

另一种方法是使用网格并设置Margin.Top和Margin.Left,它可以工作,但不允许有负边距 - 因此标签将永远不会出现在图像的左上方这对我们的需求是不能接受的。 (这不是真的,它可以出现在左上方,但当它具有负边距时,它会停止响应鼠标事件)

因此,我想知道是否有反正我可以捕获鼠标单击事件标签(MouseLeftButtonDown)然后以某种方式假装它直接来自画布 - 我相信这会解决我的问题,但我不知道它是否可能。

如果有人有任何想法,他们将非常感谢!

编辑:这是我的自定义元素的XAML。当单击TextBlock时,该元素不会触发MouseLeftButtonDown事件,但在单击该图像时会触发该事件。

<UserControl x:Class="SitePlanViewer.Components.Visual.BoreholeElement" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <Border x:Name="Border" BorderBrush="Transparent" BorderThickness="2" Margin="-5"> 
     <Canvas x:Name="MainCanvas" Margin="5" MinWidth="12" MinHeight="12"> 
      <Image x:Name="BoreholeImage" Source="/Images/BoreholeSymbol.png" VerticalAlignment="Center" Width="12" Height="12" /> 
      <TextBlock x:Name="Label" FontSize="8" Canvas.Left="40" Canvas.Top="20" /> 
     </Canvas> 
    </Border> 
</UserControl> 
+0

你能提供一些XAML例子吗?您仍应该能够在标签上获得鼠标事件(除非在其中或在父元素中禁用了命中测试)。 – 2010-11-12 12:08:27

+0

嗨,我为我的自定义元素添加了XAML。 – 2010-11-12 12:22:37

回答

2

不能自动鼠标事件的元素,因为这将打开一个安全漏洞(请记住,你只能调用某些操作来自实际的鼠标点击,如文件打开对话框,因此它们不允许模拟点击)。

您的示例工作仅用于图像,因为画布在物理上位于图像下方。

只有当画布范围直接位于鼠标下时(例如,如果您将画布变得更小,图像点击也将停止传播到画布),鼠标事件才会传播到画布。

如果增加画布的大小(例如包括标签的所有可能位置),它将获取事件,但是如果在单个页面上有多个BoreholeElements,则会有重叠的画布对象(这很明显坏)。

您可能不得不重新处理您的问题。也许一个大画布上有所有的孩子对象?

+0

我想你可能是对的。我可能不得不硬着头皮,想一个不同的解决方案。目前所有元素(矩形,椭圆,钻孔元素等)确实坐在我称为GraphicsLayer对象的内部,它们从Canvas继承,但提供了绘图功能等。但是鼠标事件处理的改变是一个巨大的变化,会打破一切我们已经有了。我认为仅仅为了能够移动钻孔标签是不值得的。使用单独的图像和标签可能会更容易。但是谢谢你的解释和建议! – 2010-11-12 16:24:24

0

您可以构建相关EventArgs对象,然后调用OnClick方法直接传递EventArgs

+0

嗨格雷格,不幸的是不是因为Adorner类直接订阅元素MouseLeftButtonDown事件才能发挥它的魔力。这允许装饰者使用FrameworkElement的任何子类,而不是为每个元素类型实现自定义的OnClick事件处理程序。 – 2010-11-12 12:19:41

+0

@Tom,我过去了。这是一个猜测;) – 2010-11-12 12:21:43

+0

没关系,感谢您的尝试! :) – 2010-11-12 12:22:54