WPF:使子元素'MinWidth / MinHeight约束Window

时间:2011-03-08 04:38:49

标签: wpf layout

我有一个WPF窗口,其中包含一个MinWidth和MinHeight的UserControl。如何阻止用户将窗口大小调整到违反UserControl最小大小的位置?

这是我正在研究的Window的简化版本。我的真实应用程序的UserControl在这里由边框替换:

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <DockPanel>
    <StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal">
      <Button Content="OK"/>
      <Button Content="Cancel"/>
    </StackPanel>
    <Border BorderBrush="Green" BorderThickness="10"
            MinWidth="200" MinHeight="150"/>
  </DockPanel>
</Window>

如果我将窗口收缩得足够小,边框的右边和底边都会被切掉。我想防止窗口变得那么小 - 我希望窗口的最小尺寸恰好是边框 最小尺寸的点。一些框架(如Delphi VCL)自动将子控件的最小大小聚合到窗口;我希望WPF也这样做,但很明显它没有。

我总是可以显式设置Window的MinWidth和MinHeight,但要正确计算它们,我必须考虑按钮'ActualHeight,这意味着等待至少一个布局传递(或手动调用Measure)。凌乱。

有没有更好的方法可以防止Window的内容调整太小?

2 个答案:

答案 0 :(得分:6)

我发现最简单的方法是告诉窗口大小调整其内容:

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

然后,一旦完成大小调整(将子元素的MinWidth和MinHeight考虑在内),运行一些将MinWidth和MinHeight设置为窗口的ActualWidth和ActualHeight的代码。此时关闭SizeToContent也是个好主意,以免窗口内容发生变化时窗口调整大小。

接下来的问题是,在哪里放这个代码?我终于确定了OnSourceInitialized:

protected override void OnSourceInitialized(EventArgs e)
{
    base.OnSourceInitialized(e);
    MinWidth = ActualWidth;
    MinHeight = ActualHeight;
    ClearValue(SizeToContentProperty);
}

我也尝试了Loaded事件,但在我的情况下,那太早了 - 在数据绑定被评估之前发生了加载,并且我的数据绑定影响了我的布局(一个带有内容绑定的Label - 它的大小绑定生效后更改)。将代码移动到OnSourceInitialized,在数据绑定后触发,纠正了问题。

(还有其他事件在绑定后触发,但在显示窗口之前 - SizeChanged和LayoutUpdated - 但是它们都会在窗口显示时多次触发,如果用户调整窗口大小,则会再次触发; OnSourceInitialized只发射一次,我认为是理想的。)

答案 1 :(得分:0)

您是否尝试过将Window中的ElementName样式绑定用于手头的UserControl?似乎将Window的MinWidth / Height绑定到Button的那些是可行的。仍然不漂亮,但一旦绑定到位就不需要额外的通行证,如果更改按钮上的值,它将适应。