WPF滚动视图控件将控件推出窗口

4

我有一个包含一些控件的 DockPanel,其中包括一个 ScrollViewer

我想要实现的效果是,ScrollViewer 可以滚动网格,而不会将其他控件推出表单底部。

然而,实际上 ScrollViewer 会扩展到窗口的高度,而不是 Button 的顶部,从而将 Button 推到表单底部。为什么会这样?我应该如何解决?

<Window x:Class="Class1.MainWindow"
    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:Class1"
    mc:Ignorable="d"
    Title="MainWindow" Height="800" Width="600"
    WindowStartupLocation="CenterScreen">
<DockPanel LastChildFill="False">
    <Menu DockPanel.Dock="Top">
        <MenuItem Header="File">
            <MenuItem Name="miQuit" Header="Quit" Click="miQuit_Click" />
        </MenuItem>
    </Menu>
    <ToolBarTray DockPanel.Dock="Top" IsLocked="True">
        <ToolBar>
            <Button Name="btnQuit" ToolBar.OverflowMode="Never" Click="btnQuit_Click">
                Quit
            </Button>
        </ToolBar>
    </ToolBarTray>
    <ScrollViewer VerticalScrollBarVisibility="Auto" DockPanel.Dock="Top" VerticalAlignment="Stretch">
        <Grid Name="gMainGrid" ScrollViewer.CanContentScroll="True">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <TextBox Grid.Column="0" Grid.Row="0"   Width="100" Margin="10,10,10,10"/>
            <TextBox Grid.Column="0" Grid.Row="1"   Width="100" Margin="10,10,10,10"/>
            <TextBox Grid.Column="0" Grid.Row="2"   Width="100" Margin="10,10,10,10"/>
            <TextBox Grid.Column="0" Grid.Row="3"   Width="100" Margin="10,10,10,10"/>
            <TextBox Grid.Column="0" Grid.Row="4"   Width="100" Margin="10,10,10,10"/>
            <TextBox Grid.Column="0" Grid.Row="5"   Width="100" Margin="10,10,10,10"/>
            <TextBox Grid.Column="0" Grid.Row="6"   Width="100" Margin="10,10,10,10"/>
            <TextBox Grid.Column="0" Grid.Row="7"   Width="100" Margin="10,10,10,10"/>
            <TextBox Grid.Column="0" Grid.Row="8"   Width="100" Margin="10,10,10,10"/>
            <TextBox Grid.Column="0" Grid.Row="9"   Width="100" Margin="10,10,10,10"/>
            <TextBox Grid.Column="0" Grid.Row="10"  Width="100" Margin="10,10,10,10"/>
            <TextBox Grid.Column="0" Grid.Row="11"  Width="100" Margin="10,10,10,10"/>
            <TextBox Grid.Column="0" Grid.Row="12"  Width="100" Margin="10,10,10,10"/>
            <TextBox Grid.Column="0" Grid.Row="13"  Width="100" Margin="10,10,10,10"/>
            <TextBox Grid.Column="0" Grid.Row="14"  Width="100" Margin="10,10,10,10"/>
            <TextBox Grid.Column="0" Grid.Row="15"  Width="100" Margin="10,10,10,10"/>
            <TextBox Grid.Column="0" Grid.Row="16"  Width="100" Margin="10,10,10,10"/>
            <TextBox Grid.Column="0" Grid.Row="17"  Width="100" Margin="10,10,10,10"/>
            <TextBox Grid.Column="0" Grid.Row="18"  Width="100" Margin="10,10,10,10"/>
            <TextBox Grid.Column="0" Grid.Row="19"  Width="100" Margin="10,10,10,10"/>
            <TextBox Grid.Column="0" Grid.Row="20"  Width="100" Margin="10,10,10,10"/>
        </Grid>
    </ScrollViewer>
    <Button Name="btnButton1" DockPanel.Dock="Bottom" Click="btnButton1_Click" >ButtonText</Button>
</DockPanel>

我想要菜单栏放在屏幕顶部,按钮放在屏幕底部,而带有ScrollViewer的网格位于中间。我错在哪了?
2个回答

2
问题在于ScrollViewer不知道应该获得多少高度。 ScrollViewer是一个控件,尝试获取其子元素所需的所有大小。 DockPanel也会提供与ScrollViewer所需的大小相同的大小,因此出现了问题。您可以使用像素(即Height = 100)来修复ScrollViewer的高度,使其成为固定高度。如果您例如显示图像旋转木马,则可能会有用。
在更一般的布局建议方面,我可能会说最好使用网格而不是DockPanel:
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="auto" />
        <RowDefinition Height="auto" />
        <RowDefinition Height="auto" />
        <!-- Next one is for middle part of the page -->
        <RowDefinition Height="*" />
        <RowDefinition Height="auto" />
    </Grid.RowDefinitions>
    <!-- your controls here -->
</Grid>

0
我发现如果将整个内容放入一个网格中,使用 DockPanel 可以实现动态高度。这似乎有效,因为现在可以为 ScrollViewer 实现动态高度。
<Window x:Class="Class1.MainWindow"
    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:Class1"
    mc:Ignorable="d"
    Title="MainWindow" Height="800" Width="600"
    WindowStartupLocation="CenterScreen">
  <Grid>
      <Grid.ColumnDefinitions>
          <ColumnDefinition />
      </Grid.ColumnDefinitions>
      <Grid.RowDefinitions>
          <RowDefinition Height="*" />
          <RowDefinition Height="Auto" />
      </Grid.RowDefinitions>
      <DockPanel Grid.Column="0" Grid.Row="0" LastChildFill="False">

然后一切都像平常一样,除了我将按钮从DockPanel移动到Grid的第二行:

        </DockPanel>
    <Button Grid.Column="0" Grid.Row="1" Name="btnButton1" DockPanel.Dock="Bottom" Click="btnButton1_Click" >ButtonText</Button>
</Grid>

Height为“Auto”的行将按其内容进行调整大小。 高度为星号(*)的行将在计算出自动调整大小后填充剩余空间。 因此,一切都可以正确地并且很好地调整大小。

或者,此时我可以完全放弃DockPanel,并将MenuToolBarTrayScrollViewerButton放在它们自己单独的网格行中,就像Emad在他们的答案中建议的那样(尽管我不确定他们示例中额外的一行是用于什么)。

    <Grid.ColumnDefinitions>
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>

我最终决定采用这种方法,所以我将其标记为答案,但我将所有内容都放在这里进行全面的解释,以便完整(以防万一有人想保留他们的DockPanel)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接