2013-05-30 76 views
4

如何強制佈局測量更新?強制佈局更新

我有簡化的佈局我有問題;當你第一次點擊按鈕時你會得到一個測量值,第二次點擊不同的值。

private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     var w = mywindow.ActualWidth; 
     gridx.Width = w; 
    } 

    private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     btn3.Width = 100; 
     var w = mywindow.ActualWidth; 
     gridx.Width = w - btn3.Width; 
     InvalidateArrange(); 
     InvalidateMeasure(); 

     MessageBox.Show(btn1.ActualWidth.ToString()); 
    } 

窗口

<Window x:Class="resizet.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded" Name="mywindow"> 

     <DockPanel HorizontalAlignment="Stretch" LastChildFill="False"> 
      <Grid HorizontalAlignment="Stretch" DockPanel.Dock="Left" Name="gridx"> 
       <Button HorizontalAlignment="Stretch" Content="btn in grid" Click="Button_Click" /> 
      </Grid> 
     <Button Name="btn2" Content="btn2" Width="0" DockPanel.Dock="Right" HorizontalAlignment="Left"></Button> 
     </DockPanel> 
</Window> 
+0

東西是不對您的設計:佈局應該更新本身自動,而不是與某人的手工製作l互動。 – Vlad

+0

當用戶單擊某個按鈕時,將打開一個新面板,並調整其他所有內容。它確實調整大小,但是第二次點擊。 –

回答

5

這解決了這個問題:

btn3.Width = 100;  
btn3.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate); 
var w = mywindow.ActualWidth; 
gridx.Width = w - btn3.Width; 

額外

private static Action EmptyDelegate = delegate() { }; 
+0

它工作的很棒! –

1

更改Width屬性必須無效自身的佈局,你並不需要調用InvalidateXXX()自己。

問題在於佈局沒有立即更新,而是在消息循環的下一次迭代中。所以ActualWidth不會立即改變。


如果你想Grid自動調整按鈕時,寬度增加,爲什麼不使用佈局管理,並把兩個到外Grid的不同列?

<Grid> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="*"/> 
     <ColumnDefinition Width="Auto"/> 
    </Grid.ColumnDefinitions> 
    <Grid x:Name="gridx" 
      Grid.Column="0"> 
     <Button HorizontalAlignment="Stretch" 
       Click="Button_Click"/> 
    </Grid> 
    <Button x:Name="btn2" 
      Content="btn2" 
      Width="0" 
      Grid.Column="1"/> 
</Grid> 

而在代碼隱藏

private void Button_Click(object sender, RoutedEventArgs e) 
{ 
    btn2.Width = 100; 
}