简体   繁体   English

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

[英]WPF: ListView inside of Scrollviewer; Layout question

i do have a question about layouting with a listview inside of a scrollviewer. 我确实有一个关于在scrollviewer中使用listview进行布局的问题。 Once a listview is inside a scrollviewer it does use it's maximum size and doesn't scroll itself cause the scrollviewer offers unlimited amount of space to the controls inside of it. 一旦listview位于scrollviewer中,它就会使用它的最大大小并且不会自动滚动,因为scrollviewer为其内部的控件提供了无限量的空间。 The problem is, that controls that are below a long list are only visible if the user scrolls down and I want to make the listview only use the space that is necessary and use a scrollbar itself. 问题是,只有当用户向下滚动并且我想使列表视图仅使用必要的空间并使用滚动条本身时,才能看到长列表下方的控件。 Pictures do tell more information than words (links for pictures also do tell much as my reputation isn't at 10 yet.. Edit2: well i can use only one link so i copied all pictures onto one). 图片确实告诉了更多的信息而不是文字(图片的链接也说得很多,因为我的声誉还不到10岁。编辑2:我只能使用一个链接,所以我将所有图片复制到一个)。 If the lists isn't long everything is okay: 如果列表不长,一切都可以:

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

Now if the list is longer the controls below move down into the invisible land: 现在如果列表更长,下面的控件会向下移动到看不见的地方:

Picture 2 : see link from picture 1 图2:见图1中的链接

What I do want to happen now is this: 我现在想做的是:

Picture 3 : see link from picture 1 图3:见图1中的链接

That itself isn't really a problem cause we could put everything in a dockpanal and do dock the controls below to Dock.Below and Top to Top and let the listview fill the center with "lastchildfill". 这本身并不是一个问题,因为我们可以将所有内容放在dockpanal中,并将下面的控件停靠到Dock.Below和Top to Top,让listview用“lastchildfill”填充中心。 Now for the real problem. 现在为真正的问题。 What if the window gets smaller? 如果窗口变小怎么办? Then at first the listview disappears and then also everything else without having a scrollbar to scroll to the controls on the bottom. 然后首先列表视图消失,然后其他所有其他内容没有滚动条滚动到底部的控件。

Picture 4 : see link from picture 1 图4:见图1中的链接

The ideal solution i am searching for is to have scrollbars on the window (or a root scrollviewer) which would enable us to scroll to every section of the window like this and just have the outer scrollbars to be visible once everything is a minimum size. 我正在寻找的理想解决方案是在窗口(或根滚动查看器)上设置滚动条,这样我们就可以像这样滚动到窗口的每个部分,只要外部滚动条在一切都是最小尺寸时可见。

Picture 5 : see link from picture 1 图5:见图1中的链接

ANY IDEAS? 有任何想法吗? too many pictures? 图片太多了? here's a little bit of xaml for everyone to try making it work (it's just a fast example windows...) 这里有一点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>

Ok. 好。 So I had the same problem, but have now managed to solve it! 所以我遇到了同样的问题,但现在已经设法解决了!

My project looks a little different than yours, but I think that it should work for you to. 我的项目看起来与你的项目略有不同,但我认为它应该适合你。 The solution that I'm presenting also has some limitation to it. 我提出的解决方案也有一些限制。 For example, it will only work if you only add one ListView ! 例如,只有添加一个ListView才能使用它! In your example you only have one, so that won't be a problem there. 在你的例子中你只有一个,所以那里不会有问题。 But for anyone that might want more ListViews , you'll have to add more functionality for deciding the sizes of the Views, and where to put them. 但对于任何可能需要更多ListView的人来说 ,您必须添加更多功能来决定视图的大小以及放置它们的位置。

You will also have to have a MinHeight set for the ListView. 您还必须为ListView设置MinHeight

My solution is to create you own panel class that extends a StackPanel , override the MeasureOverride and the ArrangeOverride functions. 我的解决方案是创建自己的面板类,扩展StackPanel ,覆盖MeasureOverrideArrangeOverride函数。 And add the ListView into the created Panel 并将ListView添加到创建的Panel中

CustomPanel: 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;
    }
}

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

It was a long time ago this question was asked, but I hope that this answer will help at least someone! 很久以前就提出了这个问题,但我希望这个答案能帮到至少一个人!

I also like to thank @sisyphe for all the help needed to solve this problem :) 我还要感谢@sisyphe提供解决此问题所需的所有帮助:)

Not sure if this is really your ideal solution, but I personnally do this quite differently: 不确定这是否真的是你理想的解决方案,但我个人的做法完全不同:

I use a simple grid, with n rows for what should be above the listvew, m rows for the stuff below and a row for the listview with height=*. 我使用一个简单的网格,其中n行应该位于listvew之上,m行用于下面的内容,列表用于heightview * *。 So everything above and below is visible, a scroll bar appears in the list view when there is not enough room. 因此,上面和下面的所有内容都是可见的,当没有足够的空间时,滚动条会出现在列表视图中。

I have a working example of this, but with a DataGrid. 我有一个这样的工作示例,但有一个DataGrid。 It should be quite similar with a ListView. 它应该与ListView非常相似。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM