2011-03-08 136 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