简体   繁体   English

ScrollViewer 中的 WPF DataGrid

[英]WPF DataGrid inside a ScrollViewer

I have a StackPanel with a header control and a DataGrid Inside a Scrollviewer ;我有一个StackPanel ,带有一个 header 控件和一个Scrollviewer内的DataGrid like so:像这样:

<ScrollViewer>
    <StackPanel Orientation="Vertical">
        <Canvas x:Name="header" 
                Height="300" />
        <DataGrid x:Name="dataGrid">
        </DataGrid>
    </StackPanel>
</ScrollViewer>

The scoll behavior should fulfill these requirements: scoll 行为应满足以下要求:

  • Scrolling while MouseOver the DataGrid should scroll the outer ScrollViewer在鼠标悬停时滚动DataGrid应滚动外部ScrollViewer
  • The header control (symbolized by Canvas ) is scrolled by the ScollViewer . header 控件(由Canvas表示)由ScollViewer滚动。

  • The horizontal scrollbar at the bottom of the DataGrid should be preserved on screen at any time. DataGrid底部的水平滚动条应随时保留在屏幕上。

  • The horizontal scrollbar should not scroll the header control, only the DataGrid .水平滚动条不应滚动 header 控件,只能滚动DataGrid

I tried various settings for the DataGrid.ScrollViewer but none have the desired effect, nor does changing the StackPanel to a WrapPanel or even Grid help any.我尝试了DataGrid.ScrollViewer的各种设置,但都没有达到预期的效果,将StackPanel更改为WrapPanel甚至Grid也没有任何帮助。

Is this possible?这可能吗? Any help and resources to read are appreciated.感谢您提供任何帮助和阅读资源。

I've been struggling with your first problem for some time as well - having an inner ScrollViewer (or DataGrid in this case) scroll the outer ScrollViewer.我也一直在努力解决您的第一个问题 - 让内部 ScrollViewer(或本例中的 DataGrid)滚动外部 ScrollViewer。 But I think I have a pretty elegant solution.但我认为我有一个非常优雅的解决方案。 You have to add an event handler to the PreviewMouseWheel event of the DataGrid (and a name to the ScrollViewer):您必须将事件处理程序添加到 DataGrid 的 PreviewMouseWheel 事件(以及 ScrollViewer 的名称):

<ScrollViewer x:Name="scroll_viewer">
    <StackPanel Orientation="Vertical">
        <Canvas x:Name="header" 
                Height="300" />
        <DataGrid x:Name="dataGrid" PreviewMouseWheel="mousewheel">
        </DataGrid>
    </StackPanel>
</ScrollViewer>

Then the event handling method:然后是事件处理方法:

private void mousewheel(object sender, MouseWheelEventArgs e)
{
    //what we're doing here, is that we're invoking the "MouseWheel" event of the parent ScrollViewer.

    //first, we make the object with the event arguments (using the values from the current event)
    var args = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta);

    //then we need to set the event that we're invoking.
    //the ScrollViewer control internally does the scrolling on MouseWheelEvent, so that's what we're going to use:
    args.RoutedEvent = ScrollViewer.MouseWheelEvent;

    //and finally, we raise the event on the parent ScrollViewer.
    scroll_viewer.RaiseEvent(args);
}

Hope this helps!希望这可以帮助!

It's a very complicated question, it probably requires a man-week to complete: But here's a start which solves half of your problem:这是一个非常复杂的问题,它可能需要一个人周才能完成:但这是一个解决一半问题的开始:

<ScrollViewer x:Name="scroll">
    <DataGrid x:Name="dataGrid">
        <DataGrid.Template>
            <ControlTemplate>
                <StackPanel Orientation="Vertical">
                    <Canvas x:Name="header" Height="300" />
                    <ItemsPresenter/>
                </StackPanel>
            </ControlTemplate>
        </DataGrid.Template>
    </DataGrid>
</ScrollViewer>

If you put the canvas inside the datagrid's template it will consider it as a part of the datagrid so canvas and datagrid will be scrolled as one.如果您将 canvas 放在数据网格的模板中,它会将其视为数据网格的一部分,因此 canvas 和数据网格将作为一个滚动。

Obviously, the datagrid template will be blank this way, showing no headers.显然,datagrid 模板将是空白的,不显示任何标题。 Therefore you need to rewrite it from the scratch.因此,您需要从头开始重写它。 You may use the default source code for this purpose.为此,您可以使用默认源代码

To find the template just search for <ControlTemplate TargetType="{x:Type DataGrid}"> in the given link.要查找模板,只需在给定链接中搜索<ControlTemplate TargetType="{x:Type DataGrid}">

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM