【问题标题】:DrawingVisual Mouse Up Event绘图Visual Mouse Up 事件
【发布时间】:2012-04-03 08:50:57
【问题描述】:

我正在开发 WPF MVVM 应用程序。它有一个继承自 Canvas 的自定义画布类。有一个窗口放置了这些自定义画布之一(使用 XAML),并且它的背景颜色设置为透明。使用 DrawingVisuals 将图形绘制到 Canvas 以绘制原始形状并将它们作为 Visual 子级添加到 Visual 树中。这工作并将我的形状呈现到屏幕上。

我在后面的 Window 代码中向 Canvas 添加了一个鼠标向上事件。当我单击画布上的任何位置时触发,除了绘制的视觉线条或填充形状的彩色区域。明确一点:

  • 如果我在绘制的形状之外单击,即在 它触发的画布。
  • 如果有一个未填充的矩形,我点击里面的空白 区域,然后鼠标向上触发。
  • 如果我点击矩形的边界线,它不会。
  • 如果我在填充的矩形内单击它不会。

来自http://msdn.microsoft.com/en-us/library/ms742254.aspx#providing_hit_testing_support 尽管我使用的是 Canvas MouseUp 事件,但它似乎应该可以工作,因为它没有 MouseLeftButtonUp 事件。在 MS 示例中,他们不使用 Canvas,而是谈论“主机容器”,但我不确定这是否相关。

如何在单击 DrawingVisual 时触发事件?为什么在绘制区域内单击而不是在其外部单击时会抑制事件?

谢谢

【问题讨论】:

    标签: .net wpf mvvm mouseevent


    【解决方案1】:

    我已经解决了这个问题。画布具有 ViewModel 设置的 RootNode 依赖属性。问题是当您将任何子项添加到画布时,您需要调用 AddVisualChild(child) 和 AddLogicalChild(child)。我必须向依赖属性添加一个属性更改回调,以便它可以调用这两种方法将它们添加为视觉和逻辑子级,否则它无法理解父子关系,这会破坏用户输入。

    感谢大家的时间。对不起,如果我没有提供足够的细节。这是一个大应用程序,因此试图仅包含相关信息。

    【讨论】:

      【解决方案2】:

      我怀疑这可能是因为 Canvas 正在为您进行命中测试,因此鼠标点击被路由到子视觉对象。

      您可以尝试从FrameworkElement 派生吗?您需要 Canvas 的某些行为吗?

      【讨论】:

      • 将我的自定义类更改为从 FrameworkElement 继承似乎完全停止了事件的触发。
      • 是的,刚刚也尝试过,没有触发任何事件。这就像你有一个没有指定背景颜色的画布。但是框架元素没有背景颜色,所以我必须删除设置该属性的 XAML。不过,颜色的东西可能是无关的。
      • FrameworkElement 不是用来监听事件的!它负责布局参与,如果你有兴趣监听事件,你需要扩展 UIElement
      • @simo FrameworkElement 是一个 UIElement 并且具有所有相同的功能(加上一些自己的功能)。而CanvasFrameworkElement,因此具有两者的所有功能(加上更多自己的功能)。
      【解决方案3】:

      你应该阅读这篇关于路由事件的文章 http://msdn.microsoft.com/en-us/library/ms742806.aspx 以及路由事件将如何穿过矩形到达主画布:)

      【讨论】:

      • 我认为这不适用于 DrawingVisuals,因为它们不继承自 UIElement 或 ContentElement,因此无法处理路由事件。反正我是这么想的。
      【解决方案4】:

      您是否尝试过订阅 PreviewMouseUp 事件以及父 Canvas 上的 MouseLeftButtonUp?以上应该可以工作,但视觉树中的某些东西可能会将事件标记为已处理,因此它不会传播。

      处理预览确保您首先获得事件(因为预览隧道向下,然后事件冒泡,但如果处理任何预览事件,则不会冒泡更多事件)。

      这里有详细的概述:http://msdn.microsoft.com/en-us/library/ms747183.aspx

      此外,如果失败,您可以随时尝试对事件使用类处理程序(基本上是对上述行为的覆盖):http://msdn.microsoft.com/en-us/library/ms747183.aspx#AddingInstanceHandlersthatAreRaisedEvenWhenEventsareMarkedHandled

      【讨论】:

      • 谢谢。我尝试了 PreviewmouseUp,但它在与 MouseUp 相同的情况下触发。
      • 我尝试为已处理的事件添加处理程序,它仅在与正常事件相同的情况下触发,我猜这表明某些事情并未将事件标记为已处理。
      • @AlanMacdonald 嗯好的,疯狂的东西。好的,这是适合您的解决方法。直接在顶部创建另一个具有相同宽度/高度的画布,并将背景设置为透明。然后订阅那个鼠标事件。是的,我知道,可怕但它应该工作。如果不是,它会告诉您 DrawingVisual 根本没有窃取鼠标事件,但您的应用程序中的其他内容是...
      • @AlanMacdonald 你不是也必须在画布中放置一些东西来托管 DrawingVisuals 吗?即:VisualCollection。也许那是在窃取事件。我的观点是视觉树中的某些东西在你的画布上并参加了活动。您是否尝试过使用 WPF Snoop 来检查可视化树以查看其生成的内容?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-15
      相关资源
      最近更新 更多