【问题标题】:WPF: ListView inside of Scrollviewer; Layout questionWPF:Scrollviewer 内的 ListView;布局问题
【发布时间】:2012-10-24 22:12:20
【问题描述】:

我确实有一个关于在滚动查看器内使用列表视图进行布局的问题。一旦列表视图位于滚动查看器内,它就会使用它的最大尺寸并且不会自行滚动,因为滚动查看器为其中的控件提供了无限量的空间。 问题是,只有在用户向下滚动时才能看到长列表下方的控件,并且我想让列表视图仅使用必要的空间并使用滚动条本身。图片确实比文字提供了更多信息(图片链接也确实说明了很多,因为我的声誉还没有达到 10.. Edit2:我只能使用一个链接,所以我将所有图片复制到一个上)。 如果列表不长,一切正常:

图一:

现在,如果列表更长,下面的控件将向下移动到不可见的土地:

图2:见图1中的链接

我现在想要发生的事情是这样的:

图3:参见图1中的链接

这本身并不是一个真正的问题,因为我们可以将所有内容放在一个dockpanal中,并将下面的控件停靠到Dock.Below和Top to Top,并让列表视图用“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>

【问题讨论】:

    标签: c# wpf listview layout scrollviewer


    【解决方案1】:

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

    我的项目看起来和你的有点不同,但我认为它应该适合你。我提出的解决方案也有一些限制。例如,只有添加一个 ListView 才有效!在您的示例中,您只有一个,因此那里不会有问题。但是对于任何可能想要更多 ListViews 的人来说,您必须添加更多功能来决定 View 的大小以及放置它们的位置。

    您还必须为 ListView 设置 MinHeight

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

    自定义面板:

    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 为解决此问题提供的所有帮助:)

    【讨论】:

      【解决方案2】:

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

      我使用了一个简单的网格,其中 n 行表示应该在 listvew 上方的内容,m 行表示下面的内容,并且一行表示高度 =* 的列表视图。所以上面和下面的一切都是可见的,当空间不足时,滚动条会出现在列表视图中。

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

      【讨论】:

      • 这与图片 3 相符,对吧?当您的窗口变得非常小时,您不会遇到与图 4 相同的问题吗?
      • 是的,如果您想避免这种情况,请在窗口上设置 MinHeight。但是,通常,这由用户自行决定。我认为在这种情况下您无能为力,而且我认为许多用户不会希望将窗口大小调整到如此小的高度。
      • 我将把它标记为答案,即使它有点像“不要让窗口变得那么小”。有什么不同的想法吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-17
      • 2019-06-10
      • 1970-01-01
      相关资源
      最近更新 更多