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>
4

2 回答 2

8

这解决了问题:

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

有额外的

private static Action EmptyDelegate = delegate() { };
于 2013-05-30T19:10:56.460 回答
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;
}
于 2013-05-30T14:41:47.637 回答