强制布局更新

时间:2013-05-30 14:37:54

标签: wpf

如何强制布局测量更新?

我简化了布局我遇到了问题;当您第一次单击按钮进行一次测量时,第二次单击不同的按钮。

   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>

2 个答案:

答案 0 :(得分:6)

这解决了问题:

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

附加

private static Action EmptyDelegate = delegate() { };

答案 1 :(得分: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;
}