WPF为ListBox添加标题,使其像DataGrid一样滚动

时间:2011-10-04 17:37:26

标签: wpf datagrid listbox scroll

我正在尝试创建一个使用ListBox和我的自定义标题的布局,它看起来像一个标尺,但是对于日期(具有明确的开始和结束日期)。目标是使外观和感觉类似于DataGrid,除了列标题行将被我的DateTape对象替换。当用户水平滚动时,DateTapeListBox都会滚动,但当用户垂直滚动时,只有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的垂直滚动条位于控件的最右侧,这意味着用户必须水平滚动才能显示滚动条。我需要随时看到滚动条。

我尝试将DateTapeListBox放入ScrollViewer,但是当垂直滚动时DateTape滚出视图。

仅供参考 - 我的CustomRectangle对象为UserControl,允许用户实时调整水平位置和宽度,以根据需要将其定位到DateTape

1 个答案:

答案 0 :(得分:2)

我最终不得不重组一下。 ListBox现在是ItemsControl嵌套在ScrollViewer内,其中隐藏了垂直滚动条(未禁用)。我还有一个独立的ScrollBar停靠在右侧,它与代码隐藏中ScrollViewer的垂直滚动条相关联。这会处理垂直滚动。最后,辅助ScrollViewer包含DateTapeItemsControl设置来处理水平滚动。

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的滚动条,但我无法让它工作。