鼠标滚动无法在具有wpf数据网格和其他UI元素的滚动查看器中工作

use*_*093 32 c# wpf wpfdatagrid

我试图弄清楚如何让鼠标滚动在wpf窗口上工作,其中包含scrollviewer和datagrid.WPF和C#代码如下

<ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid Grid.Row="0">

            <Border Name="DataGridBorder" BorderThickness="2"  Margin="1" CornerRadius="4" BorderBrush="#FF080757">
                <dg:DataGrid AutoGenerateColumns="False" Name="ValuesDataGrid" 
                         BorderThickness="0" CanUserResizeColumns="True" FontWeight="Bold" HorizontalScrollBarVisibility="Auto" 
                         CanUserReorderColumns="False" IsReadOnly="True" IsTextSearchEnabled="True" AlternationCount="2"
                         SelectionMode="Extended" GridLinesVisibility="All"                
                         HeadersVisibility="Column" CanUserAddRows="False" CanUserDeleteRows="False" CanUserResizeRows="False" CanUserSortColumns="False"
                         RowDetailsVisibilityMode="Collapsed"  SelectedIndex="0"
                         RowStyle="{StaticResource CognitiDataGridRowStyle}"
                         >

                    <dg:DataGrid.Columns>
                        <dg:DataGridTemplateColumn Header="Title" >
                            <dg:DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <StackPanel Orientation="Horizontal" >
                                        <TextBlock HorizontalAlignment="Left" VerticalAlignment="Center" Text="{Binding Path=Name}" FontWeight="Normal"  />
                                    </StackPanel>
                                </DataTemplate>
                            </dg:DataGridTemplateColumn.CellTemplate>
                        </dg:DataGridTemplateColumn>
                    </dg:DataGrid.Columns>
                </dg:DataGrid>
            </Border>
        </Grid>
        <Button Grid.Row="1" Height="90" >hello world</Button>
    </Grid>
</ScrollViewer>
Run Code Online (Sandbox Code Playgroud)

并且C#代码如下

 public partial class Window1 : Window
  {
     public Window1()
     {
        InitializeComponent();
        initialize();
      }

    public void initialize()
    {
        ObservableCollection<MyObject> testList = new ObservableCollection<MyObject>();

        for (int i = 0; i < 20; i++)
        {
            MyObject my = new MyObject("jack " + i);
            testList.Add(my);
        }

        ValuesDataGrid.ItemsSource = testList;



    }
}

public class MyObject
{
    public string Name { get; set; }



    public MyObject(string name)
    {
        Name = name;
    }
   }
Run Code Online (Sandbox Code Playgroud)

我面临的问题是,当使用鼠标滚动时,它在按钮上方时工作正常但是只要我将鼠标指针移到网格上并尝试滚动,就没有任何反应.我可以直接移动scrollviewer的滚动条.我仍然是一个wpf新手,所以任何有关如何让鼠标滚动在数据网格上工作的帮助将不胜感激.我猜这应该有一个非常简单的解决方案,但我还没弄清楚

Don*_*n B 57

我认为Dave的解决方案很好.但是,我提出的一个建议是在scrollviewer上而不是在datagrid上捕获PreviewMouseWheel事件.如果不这样做,您可能会注意到一些细微差别,具体取决于您是在滚动数据网格还是滚动条本身.原因是当鼠标悬停在滚动条上时,滚动查看器将处理滚动,而datagrid事件将在数据网格上方处理滚动.例如,在数据网格上滚动一个鼠标滚轮可能会使您在列表中更远,然后在滚动条上方滚动.如果你在scrollviewer预览事件中捕获它,滚动时都会使用相同的测量.此外,如果以这种方式捕获它,则不需要命名scrollviewer元素,因为您不需要对该对象的引用,因为您只需键入强制转换传递给scrollviewer PreviewMouseWheel事件的发送方对象.最后,我建议在事件结束时标记处理的事件,除非你因为某些原因需要在层次结构中的某个元素中捕获它.示例如下:

private void ScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
    {
        ScrollViewer scv = (ScrollViewer)sender;
        scv.ScrollToVerticalOffset(scv.VerticalOffset - e.Delta);
        e.Handled = true;
    }
Run Code Online (Sandbox Code Playgroud)


Dav*_*ave 14

我假设DataGrid不需要滚动 - 在DataGrid上设置VerticalScrollBar ="None".

DataGrid吞下鼠标滚动事件.

我发现使用PreviewMouseWheel事件来滚动您要滚动的容器.您需要命名滚动查看器以更改垂直偏移.

private void DataGrid_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
    {
       scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset-e.Delta);
    }
Run Code Online (Sandbox Code Playgroud)


Sta*_*man 8

Don B 的解决方案的一个改进是避免使用ScrollToVerticalOffset.

scv.ScrollToVerticalOffset(scv.VerticalOffset - e.Delta);
Run Code Online (Sandbox Code Playgroud)

VerticalOffset - Delta导致非常不和谐的体验。ScrollViewer 花了很多心思让移动变得更流畅。我认为它还会根据 dpi 和其他因素缩小增量...

我发现最好捕获并处理PreviewMouseWheelEvent并将 a 发送MouseWheelEvent到预期的ScrollViewer. 我的 Don B 解决方案版本如下所示。

private void ScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
    var eventArg = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta);
    eventArg.RoutedEvent = UIElement.MouseWheelEvent;
    eventArg.Source = e.Source;

    ScrollViewer scv = (ScrollViewer)sender;
    scv.RaiseEvent(eventArg);
    e.Handled = true;
}
Run Code Online (Sandbox Code Playgroud)