WPF 将标头添加到 ListBox,使其像 DataGrid 一样滚动

发布于 2024-12-08 13:08:18 字数 2050 浏览 0 评论 0原文

我正在尝试创建一个使用 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< /代码>。

I'm trying to create a layout that uses a ListBox and my custom header that looks like a ruler, but for dates (with explicit start and end dates). The goal is to have an appearance and feel similar to a DataGrid, except that the column header row would be replaced by my DateTape object. When the user scrolls horizontally, the DateTape and ListBox both scroll, but when the user scrolls vertically, only the ListBox scrolls and the DateTape stays at the top (like the column header row in the DataGrid).

So far, the best I've been able to do is as follows:

    <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>

The only problem I have with this solution is that the vertical scrollbar for the ListBox is at the extreme right of the control which means the user has to scroll horizontally to make the scrollbar appear. I need the scrollbar visible at all times.

I tried placing the DateTape and ListBox into a ScrollViewer, but then the DateTape scrolls out of view when scrolling vertically.

FYI - My CustomRectangle object is a UserControl that allows the user to adjust the horizontal position and width real-time to position it as desired in line with the DateTape.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

请你别敷衍 2024-12-15 13:08:18

我最终不得不进行一些重组。 ListBox 现在是一个嵌套在 ScrollViewer 中的 ItemsControl,其中垂直滚动条被隐藏(未禁用)。我还有一个独立的 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);
        }

我尝试通过使用 ItemsPanelTemplate 将独立的 ScrollBar 绑定到 ItemsControl 中的滚动条,但我无法做到这一点去工作。

I ended up having to restructure a bit. The ListBox is now an ItemsControl nested within a ScrollViewer with the vertical scroll bar hidden (not disabled). I also have an independent ScrollBar docked to the right side that is tied to the vertical scroll bar in the ScrollViewer in the code-behind. This handles the vertical scrolling. Finally, a secondary ScrollViewer contains the DateTape and the ItemsControl set to handle the horizontal scrolling.

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);
        }

I tried to tie the independent ScrollBar to the scroll bar in the ItemsControl through use of a ItemsPanelTemplate, but I couldn't get that to work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文