WPF добавляет заголовок в ListBox, чтобы он прокручивался как DataGrid

#wpf #datagrid #listbox #scroll

#wpf #datagrid #listbox #прокрутка

Вопрос:

Я пытаюсь создать макет, который использует ListBox и мой пользовательский заголовок, который выглядит как линейка, но для дат (с явными начальными и конечными датами). Цель состоит в том, чтобы иметь внешний вид и чувствовать себя похожим на a DataGrid , за исключением того, что строка заголовка столбца будет заменена моим DateTape объектом. Когда пользователь прокручивает по горизонтали, DateTape ListBox прокручиваются и оба, но когда пользователь прокручивает по вертикали, только ListBox прокручиваются и DateTape остаются вверху (например, строка заголовка столбца в DataGrid ).

Пока лучшее, что я смог сделать, это следующее:

     <Window x:Class="ProjectNS.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:my="clr-namespace:ProjectNS"
            Title="MainWindow" Height="350" Width="600">
        <Window.Resources>
            <DataTemplate x:Key="itemTemplate">
                <my:CustomRectangle HorizontalAlignment="Left" VerticalAlignment="Top" />
            </DataTemplate>
        </Window.Resources>
        <DockPanel>
            <Menu DockPanel.Dock="Top">
                <MenuItem Header="File" />
            </Menu>
            <ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
                <DockPanel>
                    <my:DateTape DockPanel.Dock="Top" VerticalAlignment="Top">
                        <my:DateTape.Dates>
                            <CalendarDateRange Start="10/4/2011" End="11/4/2011" />
                        </my:DateTape.Dates>
                    </my:DateTape>
                    <ListBox ItemTemplate="{StaticResource itemTemplate}" />
                </DockPanel>
            </ScrollViewer>
        </DockPanel>
    </Window>
  

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

Я попытался поместить DateTape и ListBox в a ScrollViewer , но затем DateTape прокручивается вне поля зрения при прокрутке по вертикали.

К вашему СВЕДЕНИЮ — мой CustomRectangle объект UserControl — это объект, который позволяет пользователю регулировать горизонтальное положение и ширину в режиме реального времени, чтобы расположить его по желанию в соответствии с DateTape .

Ответ №1:

В итоге мне пришлось немного реструктурировать. Теперь ListBox ItemsControl он вложен в a ScrollViewer со скрытой вертикальной полосой прокрутки (не отключен). У меня также есть независимая ScrollBar привязка к правой стороне, которая привязана к вертикальной полосе прокрутки ScrollViewer в коде. Это обрабатывает вертикальную прокрутку. Наконец, вторичный ScrollViewer файл содержит DateTape и ItemsControl набор для обработки горизонтальной прокрутки.

XAML

     <DockPanel x:Name="dockPanel">
        <Menu DockPanel.Dock="Top">
            <MenuItem Header="File" />
        </Menu>
        <ScrollBar x:Name="verticalScrollBar"
                   DockPanel.Dock="Right"
                   SmallChange="1"
                   LargeChange="3"
                   Scroll="verticalScrollBar_Scroll"
                   SizeChanged="verticalScrollBar_SizeChanged"
                   Style="{StaticResource scrollBarHiderStyle}"
                   Maximum="{Binding ElementName=listScroller, Path=ScrollableHeight}" />
        <ScrollViewer x:Name="dateScroller"
                      VerticalScrollBarVisibility="Disabled"
                      HorizontalScrollBarVisibility="Auto"
                      DockPanel.Dock="Top">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition />
                </Grid.RowDefinitions>
                <my:DateTape x:Name="dateTape"
                             DockPanel.Dock="Top"
                             VerticalAlignment="Top"
                             Dates="{Binding Source={StaticResource dateRange}}" />
                <ScrollViewer x:Name="listScroller" VerticalScrollBarVisibility="Hidden" Grid.Row="1" Foreground="{x:Null}" Panel.ZIndex="1">
                    <ItemsControl x:Name="itemsList"
                                  ItemTemplate="{StaticResource itemTemplate}"/>
                </ScrollViewer>
            </Grid>
        </ScrollViewer>
    </DockPanel>
  

C#

         // this function merely sets the scroll bar thumb size
        private void verticalScrollBar_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            verticalScrollBar.Track.ViewportSize = itemsList.ActualHeight / 2;
        }

        // this function links the scroll bar to the scrollviewer
        private void verticalScrollBar_Scroll(object sender, System.Windows.Controls.Primitives.ScrollEventArgs e)
        {
            listScroller.ScrollToVerticalOffset(e.NewValue);
        }
  

Я попытался привязать независимый ScrollBar к полосе прокрутки при ItemsControl использовании a ItemsPanelTemplate , но я не смог заставить это работать.