Для нескольких DataGrids в ScrollViewer, как мне сохранить заголовок видимой в данный момент сетки в верхней части окна? - PullRequest
0 голосов
/ 29 апреля 2020

Я не так хорош в описании вещей, поэтому извините заранее.
По сути, у меня есть неизвестное количество сеток данных, каждая из которых связана с различным источником, внутри одного большого ScrollViewer, поэтому я могу прокручивать их все .
Мне бы хотелось, чтобы заголовок сетки, которую пользователь прокручивал, был виден сверху, пока он еще виден.
Если пользователь полностью прокручивает эту сетку к другой сетке, то теперь заголовок сетки должен быть прикреплен вверху и т. д.

Итак, вот большая часть xaml:

<Window ......>
    <Window.Resources>
        <ResourceDictionary>
            <DataGrid x:Key="ItemDataGrid"
                      x:Shared="False"
                      AutoGenerateColumns="True"
                      AutoGeneratedColumns="Dg_items_AutoGeneratedColumns"
                      AutoGeneratingColumn="Dg_items_AutoGeneratingColumn"
                      CanUserAddRows="False"
                      CanUserDeleteRows="False"
                      CellEditEnding="Dg_items_CellEditEnding"
                      EnableRowVirtualization="True"
                      GotFocus="Dg_items_GotFocus"
                      HorizontalScrollBarVisibility="Disabled"
                      SelectionUnit="CellOrRowHeader"
                      Sorting="Dg_items_Sorting"
                      VerticalScrollBarVisibility="Disabled">
                <DataGrid.Resources>
                    <Style TargetType="{x:Type DataGridCell}">
                        <EventSetter Event="PreviewMouseLeftButtonDown"
                                     Handler="Dg_items_cell_MouseClick"/>
                        <EventSetter Event="MouseDoubleClick"
                                     Handler="Dg_items_cell_MouseClick"/>
                    </Style>
                </DataGrid.Resources>
            </DataGrid>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

<!-- I'm cutting out the first row, it's mostly a bar with buttons and not important. -->
<!-- This is the row with the DataGrids: -->

        <ScrollViewer Name="scroll_viewer"
                      Grid.Row="1"
                      Grid.Column="0"
                      Grid.ColumnSpan="3"
                      HorizontalScrollBarVisibility="Auto"
                      IsDeferredScrollingEnabled="True"
                      PreviewMouseWheel="ScrollViewer_PreviewMouseWheel">
            <Grid Name="grid"/>
        </ScrollViewer>

То, что <Grid Name="grid"/> есть то, что я добавляю сгенерировал DataGrids с этим:

        public DataGrid AddDataGrid<T>(IEnumerable<T> itemSource) {
            var control = new ContentControl {Content = Resources["ItemDataGrid"]};
            grid.AddControl(control);
            var dataGrid = ((DataGrid) control.Content);
            dataGrid.ItemsSource = itemSource is ObservableCollection<T> ? itemSource : new ObservableCollection<T>(itemSource);
            return dataGrid;
        }

(я не знаю, является ли это лучшим способом сделать то, что я сделал, но это работает. Кроме того, ярлыки, как правило, будут добавляться туда, один для каждой DataGrid; не так важно, но они просто смешиваются в вертикальном списке сеток.) ​​

Все сделано динамически c в коде, нет способа узнать, какие столбцы будут присутствовать во время компиляции.
Это также включает в себя сами DataGrids, и именно поэтому у нас есть AutoGeneratingColumn.

Я знаю, что это я делаю это в ScrollViewer, который предотвращает залипание заголовков, но мне нужен способ показать неопределенный число DataGrids по вертикали и не знаю лучшего решения.

Итак ... Как мне сохранить заголовки видимыми для в настоящее время видимой DataGrid в ScrollViewer?

1 Ответ

0 голосов
/ 29 апреля 2020

Я вижу одну проблему с реализацией этой задачи с использованием простого элемента управления ScrollViewer. Проблема возникает, потому что ScrollViewer имеет бесконечное пространство внутри. Это заставит ваши сетки добавлять весь их контент вместо использования RowVirtualization. Я предлагаю вам проверить свои реальные данные, насколько важной для вас будет эта проблема. Если вы видите, что ваши сетки довольно малы и проблем с производительностью нет, вы можете использовать RenderTransform для перемещения заголовков на основе текущей позиции ScrollViewer. Если вы видите проблему с производительностью, может потребоваться использование отдельного элемента управления полосой прокрутки для прокрутки сеток одна за другой и динамического расчета их высоты. Например, по умолчанию отображают только первую сетку и устанавливают высоту других на 0, и используют эту полосу прокрутки только для прокрутки ее содержимого. Когда вы прокрутите до конца, вам понадобится уменьшить высоту первой сетки и увеличить размер второй сетки, чтобы вывести ее на экран. Затем начните прокручивать вторую сетку, когда она заполнит все доступное пространство, и так далее. Похоже, нетривиальная задача с большим количеством возможных трудностей.

...