2011-03-08 135 views
6

我有一个WPF窗口,其中包含一个带有MinWidth和MinHeight的UserControl。我该如何防止用户将窗口大小调整到UserControl的最小大小被违反的地步?WPF:制作子元素MinWidth/MinHeight约束窗口

这是我正在处理的一个窗口的简化版本。我真正的应用程序的用户控件在这里换成了边框:

<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也会这样做,但显然不是。

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

有没有更好的方法来保持窗口的内容调整太小?

回答

5

我发现最简单的方法是将窗口大小告诉它的内容:

<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事件,但对我来说,那是太早 - 加载数据绑定已被评估之前发生,我不得不说影响了我的布局数据绑定(一个标签对其内容进行绑定 - 在绑定生效后其大小发生变化)。将代码移入OnSourceInitialized(在数据绑定后触发),纠正了问题。 (还有其他事件在绑定后触发,但在窗口显示之前触发 - SizeChanged和LayoutUpdated - 但是在窗口显示时它们都会触发多次,如果用户调整窗口大小,它们会再次触发; OnSourceInitialized只会触发一次,这是我认为理想的。)

+0

这个完美的作品。 – 2013-09-11 19:13:58

0

您是否尝试过使用从窗口到用户控件的ElementName样式绑定?将窗口的MinWidth/Height绑定到Button的这些似乎是可行的。仍然不太好,但是一旦绑定就绪后它不需要额外的传递,并且如果你改变了按钮上的值,它将适应。

+0

有趣的想法,虽然窗户的MinHeight将不得不基于UserControl的MinHeight +按钮的ActualHeight +窗口边框和标题的高度。所以我可能需要一个MultiBinding和一个自定义的IMultiValueConverter来做到这一点。这是你想到的吗? – 2011-03-08 10:58:26