调整内容大小以填充窗口的“客户端区域”



我在将WPF控件(在本例中我将使用Grid控件)调整为WindowClient区域的大小时遇到问题。我意识到默认情况下Grid会自动填充所有可用空间,但我要求手动设置GridWidth,以便我可以从另一个控件绑定到它(如果有任何不同,则将其列的一个Width设置为Star的DataGrid)。

请考虑以下XAML:

<Window x:Class="TestApplication.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="768" Width="1024"
        x:Name="mainWindow">
    <ScrollViewer HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Auto">
        <Grid x:Name="testGrid" Background="DarkGray">
        </Grid>
    </ScrollViewer>
</Window>

以及以下代码背后:

using System.Windows;
namespace TestApplication
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            testGrid.Width = mainWindow.Width - (SystemParameters.BorderWidth * 2);
        }
    }
}

当运行这个简单的应用程序时,Grid的宽度略大于WindowClient区域,从而显示Horizontal Scroll Bar。如果SystemParameters.BorderWidth不能准确计算Window边界的宽度,该怎么办?

根据最新的MSDN文档,SystemParameters.BorderWidth:获取用于确定非最小化窗口的非客户端区域的边框宽度的度量

这里有一种绑定客户端宽度大小而不带代码的方法:

<ScrollViewer HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Auto">
    <Grid x:Name="testGrid" Background="DarkGray" Width="{Binding Content.ActualWidth, ElementName=mainWindow}">
    </Grid>
</ScrollViewer>

这使用您命名的顶级Window,并获得其内容的实际宽度,在本例中为ScrollViewer。如果出于某种原因,您希望窗口的内容与窗口的大小不同,您可以将其封装在一个空的Grid中,这样该技术仍然有效。

在与这个尺寸问题斗争了很长一段时间后,我终于找到了一个优雅的解决方案。虽然我已经选择了@Rick Sladkey的回复作为答案(并回答了我的问题),但我想我可能会发布我的最新理解,希望它能帮助其他人。

事实证明,真正的挫折点是在处理ScrollViewer时。当VerticalScrollBar不可见时,将我的内容调整为ScrollViewerActualWidth非常有效,但当我的内容增长到垂直滚动的高度时,情况就开始崩溃。尽管我曾期望ActualWidth上的绑定可以调整我的控件大小,以适应ScrollViewer的可视区域,但实际上它保持了相同的宽度,并且可以水平滚动。

事实证明,修复方法其实很简单。与其将控件的高度或宽度(分别)绑定到ScrollViewerActualHeightActualWidth,不如将控件的宽度或高度绑定到ScrollViewerViewportHeightViewportWidth

与其手动设置宽度,不如绑定到网格的ActualWidth属性(这将为您提供一个实际值)

最新更新