WPF:Scrollviewer里面的ListView;布局问题

时间:2010-11-11 12:18:07

标签: c# wpf listview layout scrollviewer

我确实有一个关于在scrollviewer中使用listview进行布局的问题。一旦listview位于scrollviewer中,它就会使用它的最大大小并且不会自动滚动,因为scrollviewer为其内部的控件提供了无限量的空间。 问题是,只有当用户向下滚动并且我想使列表视图仅使用必要的空间并使用滚动条本身时,才能看到长列表下方的控件。图片确实告诉了更多的信息而不是文字(图片的链接也说得很多,因为我的声誉还不到10岁。编辑2:我只能使用一个链接,所以我将所有图片复制到一个)。 如果列表不长,一切都可以:

图片1:http://i.stack.imgur.com/7dDEC.jpg

现在如果列表更长,下面的控件会向下移动到无形的土地:

图2:见图1中的链接

我现在想要做的是:

图3:见图1中的链接

这本身并不是一个真正的问题,因为我们可以将所有内容放在dockpanal中并将下面的控件停靠到Dock.Below和Top to Top,让listview用“lastchildfill”填充中心。现在为真正的问题。如果窗口变小怎么办?然后首先列表视图消失,然后是其他所有内容,而没有滚动条滚动到底部的控件。

图4:见图1中的链接

我正在搜索的理想解决方案是在窗口(或根滚动查看器)上有滚动条,这样我们就可以滚动到窗口的每个部分,只需要外部滚动条一旦所有东西都是最小尺寸就可见。

图5:见图1中的链接

任何想法?图片太多了?这里有一点点xaml供大家尝试使它工作(这只是一个快速的例子窗口......)

<Window x:Class="WpfTest1.ScrollTestWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="ScrollTestWindow" Height="400" Width="700">
    <ScrollViewer >
        <DockPanel LastChildFill="True" ScrollViewer.CanContentScroll="True" ScrollViewer.HorizontalScrollBarVisibility="Visible">
            <Grid DockPanel.Dock="Top">
                <TextBlock Text="Example controls above listview" Background="LightGray" FontSize="30"></TextBlock>
            </Grid>
            <Grid DockPanel.Dock="Bottom">
                <TextBlock Text="Example controls below listview" Background="LightGray" FontSize="30"></TextBlock>
            </Grid>
            <ListView FontSize="30">
                <ListView.View>
                    <GridView>
                        <GridViewColumn Width="190" Header="Date" />
                        <GridViewColumn Width="200" Header="Day Of Week"  DisplayMemberBinding="{Binding DayOfWeek}" />
                        <GridViewColumn Width="120" Header="Year" DisplayMemberBinding="{Binding Year}" />
                    </GridView>
                </ListView.View>
                <sys:DateTime>1/1/1</sys:DateTime>
                <sys:DateTime>1/1/1</sys:DateTime>
                <sys:DateTime>1/1/1</sys:DateTime>
                <sys:DateTime>1/1/1</sys:DateTime>
                <sys:DateTime>1/1/1</sys:DateTime>
                <sys:DateTime>1/1/1</sys:DateTime>
                <sys:DateTime>1/1/1</sys:DateTime>
                <sys:DateTime>1/1/1</sys:DateTime>
            </ListView>
        </DockPanel>

    </ScrollViewer>

2 个答案:

答案 0 :(得分:4)

确定。所以我遇到了同样的问题,但现在已经设法解决了它!

我的项目与您的项目略有不同,但我认为它应该对您有用。我提出的解决方案也有一些限制。例如,它仅在您只添加一个 ListView 时才有效!在你的例子中你只有一个,所以那里不会有问题。但对于任何可能需要更多 ListViews 的人来说,您必须添加更多功能来决定视图的大小以及放置它们的位置。

您还必须为 ListView设置 MinHeight

我的解决方案是创建自己的面板类,扩展 StackPanel ,覆盖 MeasureOverride ArrangeOverride 函数。并将 ListView 添加到创建的Panel

<强> CustomPanel:

public class ScrollablePanel : StackPanel
{
    protected override Size MeasureOverride(Size constraint)
    {
        Size tmpSize = base.MeasureOverride(constraint);
        tmpSize.Height = (double)(this.Children[0] as UIElement).GetValue(MinHeightProperty);
        return tmpSize;
    }

    protected override System.Windows.Size ArrangeOverride(System.Windows.Size finalSize)
    {
        Size tmpSize = new Size(0, 0);

        //Width stays the same
        tmpSize.Width = finalSize.Width;

        //Height is changed
        tmpSize.Height = finalSize.Height;

        //This works only for one child!
        this.Children[0].SetCurrentValue(HeightProperty, tmpSize.Height);
        this.Children[0].Arrange(new Rect(new Point(0, 0), tmpSize));

        return tmpSize;
    }
}

XAML

<Window x:Class="WpfTest1.ScrollTestWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:local="clr-namespace:WpfTest1"
Title="ScrollTestWindow" Height="400" Width="700">
    <ScrollViewer >
        <DockPanel LastChildFill="True" ScrollViewer.CanContentScroll="True" ScrollViewer.HorizontalScrollBarVisibility="Visible">
            <Grid DockPanel.Dock="Top">
                <TextBlock Text="Example controls above listview" Background="LightGray" FontSize="30"></TextBlock>
            </Grid>
            <Grid DockPanel.Dock="Bottom">
                <TextBlock Text="Example controls below listview" Background="LightGray" FontSize="30"></TextBlock>
            </Grid>
            <local:ScrollablePanel>
                <ListView FontSize="30" MinHeight="80">
                    <ListView.View>
                        <GridView>
                            <GridViewColumn Width="190" Header="Date" />
                            <GridViewColumn Width="200" Header="Day Of Week"  DisplayMemberBinding="{Binding DayOfWeek}" />
                            <GridViewColumn Width="120" Header="Year" DisplayMemberBinding="{Binding Year}" />
                        </GridView>
                    </ListView.View>
                    <sys:DateTime>1/1/1</sys:DateTime>
                    <sys:DateTime>1/1/1</sys:DateTime>
                    <sys:DateTime>1/1/1</sys:DateTime>
                    <sys:DateTime>1/1/1</sys:DateTime>
                    <sys:DateTime>1/1/1</sys:DateTime>
                    <sys:DateTime>1/1/1</sys:DateTime>
                    <sys:DateTime>1/1/1</sys:DateTime>
                    <sys:DateTime>1/1/1</sys:DateTime>
                </ListView>
            </local:ScrollablePanel>
        </DockPanel>

    </ScrollViewer>
</Window>

很久以前这个问题被问到了,但我希望这个答案至少会对某人有帮助!

我还要感谢@sisyphe提供解决此问题所需的所有帮助:)

答案 1 :(得分:3)

不确定这是否真的是你理想的解决方案,但我个人的做法完全不同:

我使用一个简单的网格,其中n行应该位于listvew之上,m行用于下面的内容,列表用于height = *。因此,上面和下面的所有内容都是可见的,当没有足够的空间时,滚动条会出现在列表视图中。

我有一个工作示例,但有一个DataGrid。它应该与ListView非常相似。