【问题标题】:WPF: Making child elements' MinWidth/MinHeight constrain the WindowWPF:使子元素的 MinWidth/MinHeight 约束窗口
【发布时间】:2011-07-10 20:21:39
【问题描述】:

我有一个 WPF 窗口,其中包含一个具有 MinWidth 和 MinHeight 的 UserControl。如何防止用户将 Window 的大小调整到违反 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>

如果我将窗口缩小到足够小,边框的右边缘和下边缘就会被切断。我想防止窗口变得那么小——我希望我的窗口的最小尺寸正好是边框处于 its 最小尺寸的那个点。一些框架(如 Delphi VCL)自动将子控件的最小尺寸聚合到窗口;我希望 WPF 也能做到这一点,但显然事实并非如此。

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

有没有更好的方法来防止 Window 对其内容调整得太小?

【问题讨论】:

    标签: wpf layout


    【解决方案1】:

    您是否尝试过使用 ElementName 样式从 Window 绑定到手头的 UserControl?将 Window 的 MinWidth/Height 绑定到 Button 的 MinWidth/Height 似乎是可行的。仍然不漂亮,但一旦绑定到位,它应该不需要额外的传递,并且如果您更改 Button 上的值,它将适应。

    【讨论】:

    • 有趣的想法,虽然 Window 的 MinHeight 必须基于 UserControl 的 MinHeight + Button 的 ActualHeight + 窗口边框和标题的高度。所以我可能需要一个 MultiBinding 和一个自定义的 IMultiValueConverter 来做到这一点。这就是你的想法吗?
    【解决方案2】:

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

    <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 事件,但在我的情况下,这还为时过早 - Loaded 发生在数据绑定被评估之前,并且我的数据绑定影响了我的布局(一个带有其内容绑定的标签 - 它的大小绑定生效后更改)。将代码移动到 OnSourceInitialized 中,它在数据绑定后触发,从而解决了问题。

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

    【讨论】:

      猜你喜欢
      • 2011-10-03
      • 2010-12-15
      • 2019-06-12
      • 1970-01-01
      • 1970-01-01
      • 2021-12-25
      • 2013-02-06
      • 2011-07-16
      • 2015-10-10
      相关资源
      最近更新 更多