Now we’ll talk about a behavior of WPF VisualBrush
. Maybe it is a bug, but let’s view some details and determine whether it is or not.
The reproduction code
Let’s make a XAML layout to reproduce such an issue.
We have a large Grid
which contains an inner Grid
and an inner Border
. The Grid
contains a Rectangle
which is as large as the Grid
itself and a TextBlock
which presents some contents. The Border
only shows its background which a VisualBrush
of the Grid
.
This is the whole XAML file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <Window x:Class="Walterlv.Demo.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Walterlv 的 WindowChrome 示例窗口" Height="450" Width="800" WindowStartupLocation="CenterScreen"> <Grid> <Grid x:Name="VisualSource"> <Rectangle x:Name="VisibleOr" Fill="LightCoral" Visibility="Visible" /> <TextBlock FontSize="24" TextAlignment="Center" VerticalAlignment="Center"> <Run Text="I'm walterlv, " /> <LineBreak /> <Run Text="I'm reproducing this Visual bug." /> </TextBlock> </Grid> <Border> <Border.Background> <VisualBrush Visual="{Binding Source={x:Reference VisualSource}}" /> </Border.Background> </Border> </Grid> </Window> |
---|
This is the code-behind. Notice that it changes the visibility of the Rectangle
every 1 second.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | using System.Threading.Tasks; using System.Windows; namespace Walterlv.Demo { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); Loaded = OnLoaded; } private async void OnLoaded(object sender, RoutedEventArgs e) { while (true) { await Task.Delay(1000); VisibleOr.Visibility = Visibility.Collapsed; await Task.Delay(1000); VisibleOr.Visibility = Visibility.Visible; } } } } |
---|
To verify the issue
We know that the VisualBrush
shows and stretch the whole Visual
so we can predicate only two results:
- If the
Rectangle
is visible withVisibility
propertyVisible
, theBorder
background which contains theVisualBrush
will be exactly the same with theGrid
. - If the
Rectangle
is invisible withVisibility
propertyCollapsed
, theBorder
background which contains theVisualBrush
will stretch the whole content to theBorder
without any area of theRectangle
.
But it is the real result?
The animation picture below shows the result when the Rectangle
is visible as the startup:
The animation picture below shows the result when the Rectangle
is invisible as the startup:
Did you notice that?
Only at the very beginning when the program runs it behaves the same as we predicted. But when we change the visibility of the Rectangle
the layout never changes.
The issue?
I’ve fired this issue into GitHub and this is the link:
- The VisualBrush only refresh the visual but not the layout when the Visual visibility changes · Issue #1241 · dotnet/wpf
本文会经常更新,请阅读原文: https://blog.walterlv.com/post/visual-brush-refresh-views-only-but-not-layout-en.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 吕毅 (包含链接: https://blog.walterlv.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 ([email protected]) 。