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

Я пытаюсь создать макет, который использует ListBox и мой пользовательский заголовок, который выглядит как линейка, но для дат (с явными датами начала и окончания).Цель состоит в том, чтобы выглядеть и чувствовать себя подобно 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 в ScrollViewer, но затем DateTape прокручивается вне поля зрения при вертикальной прокрутке.

FYI - Мой CustomRectangle объект - это UserControl, который позволяет пользователю в реальном времени регулировать горизонтальное положение и ширину, чтобы позиционировать его по желанию в соответствии с DateTape.

1 Ответ

3 голосов
/ 10 октября 2011

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

1011 * 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 с помощью ItemsPanelTemplate, но не смог заставить это работать.

...