防止ScrollViewer处理鼠标滚轮事件



是否有办法防止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的Content中的网格中有一个按钮。在窗口的构造函数中,我像这样订阅按钮的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指定一个名称,并将Model绑定到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的子类,它对所有的HitTest请求都做出负面的响应,似乎可以解决你的问题——然而,它可能有你不喜欢的副作用。看看它是否适合你的需要。

首先,创建子类:
public class MyScrollViewer : ScrollViewer {
  protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters) {
    return null;
  }
}

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

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

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

最新更新