按内容限制窗口大小

时间:2012-09-03 11:48:18

标签: wpf layout sizetocontent

我希望窗口尊重内容控件的MinWidth / MinHeightMaxWidth / MaxHeight规范。

有人建议使用SizeToContent,但这只会有助于设置初始窗口大小,而不是约束。

其他建议覆盖MeasureOverride并在那里设置窗口的最小/最大高度和宽度,但这似乎有些不洁净,考虑到这样一个微不足道的问题肯定会有一个纯粹的声明性解决方案。

提到另一个似乎合理但工作的解决方案(之前已在删除的答案中提到过):将窗口MinWidth绑定到{{1}控件没有考虑窗口装饰。

3 个答案:

答案 0 :(得分:7)

如果设置初始窗口大小,以便初始布局传递中内容的MinWidth / MinHeight和MaxWidth / MaxHeight不强制实际内容大小(例如,使用Window.SizeToContent =&#34 ; WidthAndHeight"),则以下公式为真:

Window.ActualSize - Content.ActualSize = 
      Window.MinSize - Content.MinSize = Window.MaxSize - Content.MaxSize.

根据这些公式,您可以推导出以下代码:

public MainWindow()
{
    InitializeComponent();

    this.SizeChanged += OnWindowSizeChanged;
}

private static void OnWindowSizeChanged(object sender, SizeChangedEventArgs e)
{
    var window = (Window)sender;
    var content = (FrameworkElement)window.Content;

    window.MinWidth = window.ActualWidth - content.ActualWidth + content.MinWidth;
    window.MaxWidth = window.ActualWidth - content.ActualWidth + content.MaxWidth;

    window.MinHeight = window.ActualHeight - content.ActualHeight + content.MinHeight;
    window.MaxHeight = window.ActualHeight - content.ActualHeight + content.MaxHeight;

    window.SizeChanged -= OnWindowSizeChanged;
}

我不知道如何使用纯声明方法有效地实现这一点,因为代码应该在初始布局传递后运行一次。

答案 1 :(得分:5)

  

有人建议使用SizeToContent,但这只会有助于设置初始窗口大小,而不是约束。

我通过在窗口初始化之后设置MinWidthMinHeight属性来解决这个问题:

<强> MainWindow.xaml

<Window ... SizeToContent="WidthAndHeight">
    ...
</Window>

<强> MainWindow.xaml.cs

public MainWindow()
{
    InitializeComponent();
    SourceInitialized += (s, e) =>
    {
        MinWidth = ActualWidth;
        MinHeight = ActualHeight;
    };
}

答案 2 :(得分:1)

使用绑定标记扩展。绑定是wpf说这个属性(源)更改时更新某些其他属性(目标)的方式。在这种情况下,Grid的MinWidth属性是Source,您的窗口的MinWidth属性是目标。

<Window x:Class="MinMaxValuesOnWindows.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="600" Width="800"
    MinWidth="{Binding ElementName=gridy, Path=MinWidth}"
    MinHeight="{Binding ElementName=gridy, Path=MinHeight}"
    MaxWidth="{Binding ElementName=gridy, Path=MaxWidth}"
    MaxHeight="{Binding ElementName=gridy, Path=MaxHeight}">
    <Grid Name="gridy"  MinHeight="80" MinWidth="80" MaxHeight="300" MaxWidth="300"/>
</Window>

正如您在主题中提到的,这并不完全有效,但您可以在绑定上使用转换器在更新绑定目标之前添加窗口框架的高度和宽度(可能需要PInvoke)。由于我怀疑窗口框架厚度在您的应用程序中是动态变化的,因此这可能只是常量值(如果用户更改主题,则不一定正确)。