WPF布局问题...如何滚动和自动调整内容大小?

时间:2010-06-21 15:16:22

标签: wpf layout datagrid grid

所有

我来自主要的ASP.NET背景,但也有使用Windows窗体的经验。我正在尝试学习如何布局我的WPF应用程序。我有以下代码:

<Grid>

    <Grid.RowDefinitions>
        <RowDefinition Height="40" />
        <RowDefinition Height="*" />
        <RowDefinition Height="40" />
    </Grid.RowDefinitions>

    <Button Grid.Row="0" Width="80" Content="Do Something"
            HorizontalAlignment="Right" Margin="5" />

    <DataGrid Grid.Row="1" Name="dgGrid" AutoGenerateColumns="True" />

    <Button Grid.Row="2" Width="80" Content="Do Something Else"
            HorizontalAlignment="Right" Margin="5" />

</Grid>

当DataGrid很短时,顶行和底行是我所期望的......在窗口的顶部和底部,中心行占据了剩余的可见空间。但是,当DataGrid太长时,底部行被强制离屏。有没有办法让DataGrid在太长而无法放入可见空间时滚动?

将中心行的高度设置为固定值会导致DataGrid滚动,但我希望在调整窗口大小时高度是动态的。

感谢任何帮助...

谢谢, 娄

5 个答案:

答案 0 :(得分:1)

您可以使用停靠面板解决此问题。在停靠面板中,添加第一个按钮并将其停靠在顶部。然后添加第二个按钮并将其停靠在底部。现在添加datagrid。确保DockPanel LastChildFill为true。这将为您提供所需的结果。我没有测试代码,所以你可能需要很少的调整,但它应该可以工作。

<DockPanel LastChildFill="True">
<Button DockPanel.Dock="Top" Width="80" Content="Do Something"
        HorizontalAlignment="Right" Margin="5" />

<Button DockPanel.Dock="Bottom" Width="80" Content="Do Something Else"
        HorizontalAlignment="Right" Margin="5" />

  

答案 1 :(得分:0)

尝试使用ScrollViewer:

<ScrollViewer Grid.Row="1">
    <DataGrid Name="dgGrid" AutoGenerateColumns="True" />
</ScrollViewer>

答案 2 :(得分:0)

我不是100%确定我正在跟踪你的问题,但如果我说得对,以下是一些建议:

  • 当窗体调整大小时,您的按钮会消失,因为窗体会缩小到可视区域的下方。您可以通过向窗口添加“MinHeight”来限制此项,例如:`MinHeight =“240”。这将阻止用户将表单缩小到阈值以下并使控件“消失”。
  • 设置行的最小高度,使它们始终可见并且不会消失(只要它大于固定行的高度[80 +中间],上面将会解决这个问题。行高]建议:

    <Grid.RowDefinitions>
        <RowDefinition Height="40" MinHeight="40" />
        <RowDefinition Height="*" MinHeight="120" />
        <RowDefinition Height="40" MinHeight="40" />
    </Grid.RowDefinitions>
    
  • 数据网格应自动拥有滚动条,除非该属性已被更改,但您可以仔细检查VerticalScrollBarVisibility="Auto"

答案 3 :(得分:0)

(抱歉,还不能发表评论......)

我的问题不是最小高度,而是最大高度。我不希望DataGrid扩展到可见区域之外,但确实如此。如果我在中心行显式设置高度,DataGrid的滚动按预期启动,但如果我使用“*”作为高度,DataGrid将扩展到可视区域。因此,如果“=”代表窗口,则表示我正在体验的内容......

===================================
= ROW 0 - Button                  =
= _______________________________ =
= ROW 1 - DataGrid                =
=     --------------------------- =
=     --------------------------- =
=     --------------------------- =
=     --------------------------- =
===================================
      ---------------------------
      ---------------------------
      ---------------------------
      ---------------------------
  _______________________________
  ROW 2 - Button

ScrollViewer也无法正常工作。

谢谢!

答案 4 :(得分:0)

娄,

我也在努力解决这个问题。有一个解决方案,但它似乎在Windows XP上运行得不好。诀窍是通过创建一个空的占位符行来为DataGrid保留空间。将DataGrid移动到布局网格之外并设置边距,如下所示。

<Grid SizeChanged="Grid_SizeChanged">
    <Grid.RowDefinitions>
        <RowDefinition Height="40" />
        <RowDefinition Name="DetailGridRow" Height="*" />
        <RowDefinition Height="40" />
    </Grid.RowDefinitions>
    <Button Grid.Row="0" Width="80" Content="Do Something" Margin="5" />
    <Button Grid.Row="2" Width="80" Content="Do Something Else" Margin="5" />
</Grid>
<DataGrid Margin="0,40,0,40" Name="dgGrid" AutoGenerateColumns="True" />

现在把这个SizeChanged处理程序放在你的代码后面。

/// <summary>
/// In order to prevent the datagrid from growing vertically the size is set to an empty
/// Grid row's size.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Grid_SizeChanged(object sender, SizeChangedEventArgs e)
{
    Grid layoutGrid = sender as Grid;
    double marginWidth = (layoutGrid.Margin.Left + layoutGrid.Margin.Right);
    double marginHeight = (layoutGrid.Margin.Top + layoutGrid.Margin.Bottom);
    double minHeight = dgGrid.MinHeight;

    if (e.HeightChanged)
        dgGrid.Height = DetailGridRow.ActualHeight > minHeight ?
        DetailGridRow.ActualHeight - marginHeight : minHeight - marginHeight;
    if (e.WidthChanged)
        dgGrid.Width = layoutGrid.ActualWidth - marginWidth;

    e.Handled = false;
}

正如我之前提到的,这种技术在Windows XP上存在问题。我遇到的问题是列宽全部搞乱,导致网格无法使用,除非您找到“魔术”列并双击它的列分隔符,这会将所有列宽恢复到正确的大小。我还在努力解决这个问题。