C# 如何创建引用多个控件的WPF行为?

C# 如何创建引用多个控件的WPF行为?,c#,wpf,mvvm,C#,Wpf,Mvvm,我有一个包含大图像的ScrollViewer。我希望用户能够按住鼠标并拖动图像以将其左右移动,我正在尝试使用一种行为来实现这一点。问题在于,当用户按下鼠标按钮时,鼠标按下事件似乎无法在ScrollViewer上触发。如果有代码隐藏,我会在图像上处理该事件,但如果行为只附加到一个控件,我不知道如何处理该问题 我应该使用什么方法来创建附加到两个对象的System.Windows.Interactivity.Behavior?您不需要附加到元素就可以向其添加事件处理程序。如果您的AssociatedO

我有一个包含大图像的ScrollViewer。我希望用户能够按住鼠标并拖动图像以将其左右移动,我正在尝试使用一种行为来实现这一点。问题在于,当用户按下鼠标按钮时,鼠标按下事件似乎无法在ScrollViewer上触发。如果有代码隐藏,我会在图像上处理该事件,但如果行为只附加到一个控件,我不知道如何处理该问题


我应该使用什么方法来创建附加到两个对象的System.Windows.Interactivity.Behavior?

您不需要附加到元素就可以向其添加事件处理程序。如果您的
AssociatedObject
ScrollViewer
,则您可能能够获得对图像的引用,如下所示:

var image = AssociatedObject.Content as Image;
然后可以添加鼠标事件处理程序:

image.MouseLeftButtonDown += (s, e) => Debug.WriteLine("Clicked!");

因此,您所附加到的对象,即关联的对象,是您的“主基地”,但您可以使用任何您可以接触到的对象,包括使用
VisualTreeHelper
在视觉树上漫游。

鼠标悬停按钮向下事件在ScrollViewer上正常引发。问题是ScrollViewer正在处理事件本身(e.Handled=true)。既然它已经被处理了,你的行为就不要接受它

根据您正在做的事情,您可能只需要使用PreviewMouseLeftButtonDown事件即可。这样一来,ScrollViewer是否会处理它就无关紧要了,因为行为首先接收它


您还可以尝试直接使用拖放事件。但我不确定这是否有效

澄清一下:你是说即使用户不是在图像上而是在scrollviewer上鼠标向下移动,你也要开始拖动图像?图像应该占据scrollviewer的全部内容,所以除了滚动条,是的。你的意思是图像在到达滚动查看器之前正在处理事件本身吗?不是。。。如果我回忆正确,ScrollViewer正在处理事件。可能通过鼠标按钮向下覆盖。不太清楚如何以及为什么,但最终你在订阅活动时不会得到通知,因为它不知何故已经由某人处理了。嗯。。。我不知道js事件冒泡(事实上,我对js一点都不了解)。但很可能是这样的。WPF使用的是两次传递事件路由(可能会有不同的名称,但你知道我的意思,对吧?)。首先,事件从顶部节点(最有可能是主窗口)开始沿着可视树向下挖掘。这些是预览活动。当事件到达实际引发它的控件时,方向将反转,事件将在可视化树中冒泡,直到到达根节点(窗口)。如果有人通过设置handled标志沿途截获事件,则事件将不再路由。当scroll viewer处理鼠标事件时,您再也看不到它了。即使您处于同一级别,scoll查看器本身也会首先被调用,您会被卡住。当您订阅隧道事件时,您将在ScrollViewer有机会处理它之前收到通知。但是,您必须小心隧道事件:如果您在图像中嵌套了一个按钮(这是不可能的,但无论如何),您将通过处理预览事件获得异常行为。该按钮还将“吞咽”事件,以防止用户使用该按钮时父控件对单击作出反应。当您使用隧道事件而不是冒泡事件时,您不会知道用户实际单击了按钮,启动平移操作并执行按钮所做的任何操作。这很可能就是scoll查看器处理事件的原因。我希望这不会让人困惑:)