阻止 ScrollViewer 处理鼠标滚轮事件

Prevent ScrollViewer from handling Mouse Wheel Event

有没有办法阻止 ScrollViewer 处理鼠标滚动?

以下代码是不够的,因为该事件应由 ScrollViewer 的子元素处理:

private void ScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
     e.Handled = true;
}

编辑-@Anders Keller Carstensen

我以前直接实例化一个PlotModel对象,所以没看到AddHandler()方法。我现在更改了我的代码,但情节没有显示任何内容:

public OxyPlot.Wpf.PlotView Plot { get; set; }

public MainWindow()
{
    InitializeComponent();
    DataContext = this;

    Plot = new OxyPlot.Wpf.PlotView();
    Plot.Model = new PlotModel();

    Plot.AddHandler(System.Windows.UIElement.PreviewMouseWheelEvent, new MouseWheelEventHandler(Plot_PreviewMouseWheel), true);

    // Create Line series
    var s1 = new LineSeries();
    s1.Points.Add(new DataPoint(2, 7));
    s1.Points.Add(new DataPoint(7, 9));
    s1.Points.Add(new DataPoint(9, 4));

    // add Series and Axis to plot model
    Plot.Model.Series.Add(s1);
    Plot.Model.InvalidatePlot(false);
}

private void ScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
    e.Handled = true;
}

private void Plot_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
    MessageBox.Show("Button_PreviewMouseWheel");
}

这是对应的XAML:

<ScrollViewer Margin="0,25,0,0" PreviewMouseWheel="ScrollViewer_PreviewMouseWheel">
    <oxy:PlotView Model="{Binding Plot}" Height="2000" Margin="0,0,15,0" />
</ScrollViewer>

我确定Model="{Binding Plot}"是错误的,但我不知道该写什么。

编辑 - 这是一个更好的解决方案。

您可以在 ScrollViewer 的 PreviewMouseWheel 事件处理程序中设置 e.Handled = true,然后仍然在您的其他控件中处理该事件。

例如,假设我在 ScrollViewer 的内容中的网格内有一个按钮。在 window 的构造函数中,我订阅了按钮的 PreviewMouseWheel 事件,如下所示:

public ScrollViewerWindow() {
  InitializeComponent();

  btn.AddHandler(UIElement.PreviewMouseWheelEvent, 
                 new MouseWheelEventHandler(Button_PreviewMouseWheel), 
                 true // Handler will be called even though e.Handled = true
                );
}

那么您的事件句柄将如下所示:

private void ScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e) {
  e.Handled = true;
}

private void Button_PreviewMouseWheel(object sender, MouseWheelEventArgs e) {
  MessageBox.Show("Button_PreviewMouseWheel");
}

这是对您的新问题的回答。

在 XAML 中为 PlotView 命名,并将模型绑定到 PlotModel 属性。

<ScrollViewer Margin="0,25,0,0" PreviewMouseWheel="ScrollViewer_PreviewMouseWheel">
    <oxy:PlotView x:Name="pv" Model="{Binding PlotModel}" Height="2000" Margin="0,0,15,0" />
</ScrollViewer>

在您的代码隐藏中,您应该添加 PlotModel 属性 并对其进行初始化:

public PlotModel PlotModel { get; set; }

public MainWindow()
{
    InitializeComponent();
    DataContext = this;

    pv.AddHandler(System.Windows.UIElement.PreviewMouseWheelEvent, new MouseWheelEventHandler(Plot_PreviewMouseWheel), true);

    // Create Line series
    var s1 = new LineSeries();
    s1.Points.Add(new DataPoint(2, 7));
    s1.Points.Add(new DataPoint(7, 9));
    s1.Points.Add(new DataPoint(9, 4));

    // add Series and Axis to plot model
    PlotModel = new PlotModel();
    PlotModel.Series.Add(s1);
    PlotModel.InvalidatePlot(false);
}

private void ScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
    e.Handled = true;
}

private void Plot_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
    MessageBox.Show("Plot_PreviewMouseWheel");
}

旧解:

创建一个 ScrollViewer 的子 class 来响应所有 HitTest 请求似乎可以解决您的问题 - 但是,它可能会产生您不喜欢的副作用。检查一下,看看它是否适合您的需求。

首先,创建子class:

public class MyScrollViewer : ScrollViewer {
  protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters) {
    return null;
  }
}

然后,在 XAML 中,将 <ScrollViewer> 更改为 <local:MyScrollViewer>

确保已声明本地命名空间。它看起来像这样:

<Window ....
        xmlns:local="clr-namespace:WPFTest">