【问题标题】:WPF multiple listview in single scrollviewer单个滚动查看器中的 WPF 多个列表视图
【发布时间】:2016-06-02 13:30:41
【问题描述】:

我正在尝试构建一个具有三个不确定长度的数据绑定列表视图控件的窗口。我希望这三个都在一个滚动视图中。

简单来说,下面的代码就是我希望它工作的方式。当然,示例 xaml 代码的结果是 scrollviewer 内容超出了窗口并且不可滚动。

我尝试使用网格控件,但效果并不理想。我不想为每个列表视图设置固定的高度和单独的滚动条,因为可能存在可变数量的数据,这会导致不必要的滚动。

谁能提供一种在一个滚动条中包含多个可变内容列表视图的方法?

<Window x:Class="AmultiListTest"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:SomeNamespace"
    mc:Ignorable="d"
    Title="AmultiListTest"
    Height="300"
    Width="300">
<StackPanel>
    <ScrollViewer>
        <StackPanel Height="250">
            <Label>List number one</Label>
            <ListView>
                <ListViewItem>list 1 Item 1</ListViewItem>
                <ListViewItem>list 1 Item 2</ListViewItem>
                <ListViewItem>list 1 Item 3</ListViewItem>
                <ListViewItem>list 1 Item 4</ListViewItem>
                <ListViewItem>list 1 Item 5</ListViewItem>
                <ListViewItem>list 1 Item 6</ListViewItem>
                <ListViewItem>list 1 Item 7</ListViewItem>
                <ListViewItem>list 1 Item 8</ListViewItem>
                <ListViewItem>list 1 Item 9</ListViewItem>
            </ListView>
            <Label>List number two</Label>
            <ListView>
                <ListViewItem>list 2 Item 1</ListViewItem>
                <ListViewItem>list 2 Item 2</ListViewItem>
                <ListViewItem>list 2 Item 3</ListViewItem>
                <ListViewItem>list 2 Item 4</ListViewItem>
                <ListViewItem>list 2 Item 5</ListViewItem>
                <ListViewItem>list 2 Item 6</ListViewItem>
            </ListView>
            <Label>List number three</Label>
            <ListView>
                <ListViewItem>list 3 Item 1</ListViewItem>
                <ListViewItem>list 3 Item 2</ListViewItem>
                <ListViewItem>list 3 Item 3</ListViewItem>
                <ListViewItem>list 3 Item 4</ListViewItem>
            </ListView>
        </StackPanel>
    </ScrollViewer>
</StackPanel>

【问题讨论】:

  • 就在我的脑海中,我建议您尝试从内部 StackPanel 中移除 250 的固定高度,并将外部 StackPanel 更改为网格。 Grid 将符合其父级(在本例中为 Window)的大小。这将强制 Grid 的内容 (ScrollViewer) 符合 Grid 的大小,这将触发 ScrollViewer 的滚动行为。如果这不起作用,至少您不会浪费太多时间尝试它。
  • 并移除外部 StackPanel - 你给它无限的高度。使用网格。

标签: wpf


【解决方案1】:

首先去掉堆栈面板的高度:

<StackPanel Height="250">

<StackPanel>

然后绑定滚动条的高度

(...)
<ScrollViewer Height="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Border}},Path=ActualHeight}">
  (...)
</ScrollViewer>

来源:How can I get ScrollViewer to work inside a StackPanel?

【讨论】:

  • 无需绑定ScrollViewer的高度。正如问题的 cmets 中所说,将外部 StackPanel 替换为 Grid。作为一般规则,当您可以使用常规布局时,永远不要绑定 Width 或 Height。
  • 此解决方案 - 或切换到外部控件的网格,两者都有效。但是,当我尝试添加一个标题(不会滚动)时,我遇到了它被覆盖的问题(如果是网格),或者高度的相对值现在太长了。有没有办法可以从上面的相对高度绑定中扣除标题的高度?
【解决方案2】:

已发布的 Scrollviewer 高度解决方案有效。我找到了一种方法来包含标题,方法是在后面添加一个代码,以通过标题堆栈面板的高度减少滚动查看器的高度。这是 XAML:

<Window x:Class="AmultiListTest"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:SomeNamespace"
    mc:Ignorable="d"
    Title="AmultiListTest"
    Height="300"
    Width="300"
    Loaded="Window_Loaded">
<StackPanel>
    <StackPanel x:Name="SPheader">
        <Label>this is header one</Label>
        <Label>this is header two</Label>
        <Separator />
    </StackPanel >
    <ScrollViewer x:Name="SViewer"
                  Height="{Binding ActualHeight, RelativeSource={RelativeSource AncestorType={x:Type Border}, Mode=FindAncestor}}">
        <StackPanel>
            <Label Content="List number one" />
            <ListView>
                <ListViewItem Content="list 1 Item 1" />
                <ListViewItem Content="list 1 Item 2" />
                <ListViewItem Content="list 1 Item 3" />
                <ListViewItem Content="list 1 Item 4" />
                <ListViewItem Content="list 1 Item 5" />
                <ListViewItem Content="list 1 Item 6" />
                <ListViewItem Content="list 1 Item 7" />
                <ListViewItem Content="list 1 Item 8" />
                <ListViewItem Content="list 1 Item 9" />

            </ListView>
            <Label Content="List number two" />
            <ListView>
                <ListViewItem Content="list 2 Item 1" />
                <ListViewItem Content="list 2 Item 2" />
                <ListViewItem Content="list 2 Item 3" />
                <ListViewItem Content="list 2 Item 4" />
                <ListViewItem Content="list 2 Item 5" />
                <ListViewItem Content="list 2 Item 6" />

            </ListView>
            <Label Content="List number three" />
            <ListView>
                <ListViewItem Content="list 3 Item 1" />
                <ListViewItem Content="list 3 Item 2" />
                <ListViewItem Content="list 3 Item 3" />
                <ListViewItem Content="list 3 Item 4" />
            </ListView>
        </StackPanel>
    </ScrollViewer>

</StackPanel>

在windows加载的代码后面我有以下行...

Public Class AmultiListTest
Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs)
    SViewer.Height = SViewer.Height - SPheader.ActualHeight
End Sub
End Class

最好不要隐藏代码,而是在 XAML 中扣除标头的实际值,但我不知道该怎么做。这段代码现在有效。


编辑:一个适当的解决方案 - 无需绑定 ScrollViewer 的高度或在后面的代码中设置它 - 如下所示:

<Window ... />
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <StackPanel x:Name="SPheader" Grid.Row="0">
            ...
        </StackPanel >
        <ScrollViewer x:Name="SViewer" Grid.Row="1">
            ...
        </ScrollViewer>
    </Grid>
</Window>

【讨论】:

  • 您后面的代码替换了高度绑定,因此您也可以从 XAML 中删除绑定。除此之外,所有这些绑定或代码背后的东西都是完全多余的。您应该改用标准的 WPF 布局机制。例如。用两行网格替换外部 StackPanel(并将第一行的高度设置为自动)。查看我的编辑。
  • 感谢网格评论。我对 WPF 比较陌生,很欣赏输入和示例。我正在处理的窗口要复杂得多,涉及多个部分并控制 wazoo。许多动态元素是根据用户输入动态构建的,因此堆栈面板使这更容易上手。我会进一步研究 Grid 的使用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多