我有一个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>
Run Code Online (Sandbox Code Playgroud)
如果我将窗口缩小到足够小,则边框的右边和底边被切掉.我想阻止窗口越来越小-我希望我的窗口的最小尺寸是正好在其边界是在点的最小尺寸.一些框架(如Delphi VCL)自动将子控件的最小大小聚合到窗口; 我希望WPF也这样做,但很明显它没有.
我总是可以显式设置Window的MinWidth和MinHeight,但为了正确计算它们,我必须考虑按钮的ActualHeight,这意味着等待至少一个布局传递(或手动调用Measure).乱.
有没有更好的方法来防止Window的内容调整太小?
我找到的最简单的方法是告诉Window调整其内容的大小:
<Window ... SizeToContent="WidthAndHeight" ...>
Run Code Online (Sandbox Code Playgroud)
然后,一旦完成大小调整(将子元素的MinWidth和MinHeight考虑在内),运行一些将MinWidth和MinHeight设置为窗口的ActualWidth和ActualHeight的代码.此时关闭SizeToContent也是个好主意,以免窗口内容发生变化时调整窗口大小.
接下来的问题是,在哪里放这个代码?我终于确定了OnSourceInitialized:
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
MinWidth = ActualWidth;
MinHeight = ActualHeight;
ClearValue(SizeToContentProperty);
}
Run Code Online (Sandbox Code Playgroud)
我也尝试了Loaded事件,但在我的情况下,那太早了 - 在数据绑定被评估之前发生了加载,并且我的数据绑定影响了我的布局(一个带有内容绑定的Label - 它的大小在绑定生效).将代码移动到OnSourceInitialized,在数据绑定后触发,纠正了问题.
(还有其他事件在绑定后触发,但在显示窗口之前 - SizeChanged和LayoutUpdated - 但它们都会在显示窗口时多次触发,如果用户调整窗口大小,则会再次触发; OnSourceInitialized仅触发一次,我认为理想.)