wpf 强制布局更新
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16839057/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Forcing layout update
提问by David Daks
How to force the layout measurements update?
如何强制布局测量更新?
I have simplified layout I am problem with; when you click the button first time you get one measurement and on the second click different one.
我简化了我遇到的问题;当您第一次单击按钮时,您会得到一个测量值,第二次单击不同的测量值。
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
窗户
<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>
回答by Daniel
This fixes the problem:
这解决了这个问题:
btn3.Width = 100;
btn3.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate);
var w = mywindow.ActualWidth;
gridx.Width = w - btn3.Width;
with additional
加上额外的
private static Action EmptyDelegate = delegate() { };
回答by Vlad
Changing the Widthproperty must invalidate the layout on its own, you don't need to call InvalidateXXX()yourself.
更改Width属性必须自行使布局无效,您无需调用InvalidateXXX()自己。
The catch is that the layout is not updated immediately, but on the next iteration of the message loop. So the ActualWidthwill not be changed immediately.
问题是布局不会立即更新,而是在消息循环的下一次迭代中更新。所以ActualWidth不会立即更改。
If you want the Gridto resize automatically when the button width is increasing, why not use the layout management and put the both into different columns of an outer Grid?
如果您希望在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>
And in code-behind
在代码隐藏中
private void Button_Click(object sender, RoutedEventArgs e)
{
btn2.Width = 100;
}

