原文:WPF 的 VisualBrush 只刷新显示的视觉效果,不刷新布局范围

WPF 的 VisualBrush 可以帮助我们在一个控件中显示另一个控件的外观。这是非常妙的功能。

但是本文需要说其中的一个 Bug —— 如果使用 VisualBrush 显示另一个控件的外观,那么只会在其显示效果有改变的时候刷新,而不会在目标布局改变的时候刷新布局。


用于复现问题的代码

我们现在做一个可以用于验证此问题的布局。

在一个大的 Grid 容器中有一个 Grid 和一个 Border,这个 Grid 将放一个大面积的 Rectangle 和一个表示内容的 TextBlock;而那个 Border 将完全以 VisualBrush 的形式呈现,呈现的内容是此 Grid 中的全部内容。

它的完整 XAML 代码如下:

<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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

其后台 C# 代码如下,包含每隔 1 秒钟切换 Rectangle 可见性的代码。

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;
}
}
}
}
  • 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

验证问题

我们知道,VisualBrush 在默认情况下会将 Visual 中的全部内容拉伸到控件中显示,于是可以预估出两个可能的结果:

  • 如果 Rectangle 可见(Visibility 为 Visible),那么 Border 中以 VisualBrush 显示的内容将完全和下面重叠(因为大小相同,拉伸后正好重叠)。
  • 如果 Rectangle 不可见(Visibility 为 Collapsed),那么 Border 中以 VisualBrush 显示的内容将仅有文字且拉伸到整个 Border 范围。

然而实际运行真的是这样子吗?

下面的动图是 Rectangle 初始状态可见时,窗口运行后的结果:

下面的动图是 Rectangle 初始状态不可见时,窗口运行后的结果:

注意到了吗?

只有初始状态才能正确反应我们之前预估出的结果,而无论后面怎么再改变可见性,布局都不会再刷新了。只是——后面 VisualBrush 的内容始终重叠。这意味着 VisualBrush 中目标 Visual 的范围增大之后不会再缩小了。

问题?

这是问题吗?

于是在以下 issue 中跟进此问题:

VisualBrush 的其他 Bug

参见:


我的博客会首发于 https://blog.walterlv.com/,而 CSDN 会从其中精选发布,但是一旦发布了就很少更新。

如果在博客看到有任何不懂的内容,欢迎交流。我搭建了 dotnet 职业技术学院 欢迎大家加入。

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名吕毅(包含链接:https://walterlv.blog.csdn.net/),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。

发布了382 篇原创文章 · 获赞 232 · 访问量 47万+

WPF 的 VisualBrush 只刷新显示的视觉效果,不刷新布局范围的更多相关文章

  1. 浅谈WPF的VisualBrush

    首先看看VisualBrush的解释,msdn上面的解释是使用 Visual 绘制区域,那么我们再来看看什么是Visual呢?官方的解释是:获取或设置画笔的内容,Visual 是直接继承自Depend ...

  2. WPF文本框只允许输入数字

    XAML代码   < TextBox Height="23" HorizontalAlignment="Left" Margin="100,5, ...

  3. WPF 同一个程序 只允许 同时运行一个

            方法2  当程序已经运行了 再运行这个程序时,则显示当前这个窗体  http://code.3rbang.com/cshape-run-one/ VS2013附件:http://fil ...

  4. wpf程序,只允许运行一个程序实例问题

    https://bbs.csdn.net/topics/390486402 https://codereview.stackexchange.com/questions/20871/single-in ...

  5. Prism+MaterialDesign+EntityFramework Core+Postgresql WPF开发总结 之 中级篇

    本着每天记录一点成长一点的原则,打算将目前完成的一个WPF项目相关的技术分享出来,供团队学习与总结. 总共分三个部分: 基础篇主要争对C#初学者,巩固C#常用知识点: 中级篇主要争对WPF布局与Mat ...

  6. 逆天通用水印支持Winform,WPF,Web,WP,Win10。支持位置选择(9个位置 ==》[X])

    常用技能:http://www.cnblogs.com/dunitian/p/4822808.html#skill 逆天博客:http://dnt.dkil.net 逆天通用水印扩展篇~新增剪贴板系列 ...

  7. 将非WPF window设为 WPF Window的Owner

    如果WPF Content是寄宿在Win32 窗体或Windows Form中,则在WPF模块中可能不会存在WPF Window(WPF模块的根可能是个UserControl).如果在WPF模块中弹出 ...

  8. WPF, WPF Browser Application(XBAP) 和 Silverlight 的区别

    由图可见,XBAP与WPF的区别是“受限的”:Silverlight与XBAP的区别是,不需要.NET Framework. 上星期與以前的同事爭論著究竟使用XBAP來開發XX用戶端 (為筆者之前開發 ...

  9. [WPF自定义控件库]使用WindowChrome的问题

    1. 前言 上一篇文章介绍了使用WindowChrome自定义Window,实际使用下来总有各种各样的问题,这些问题大部分都不影响使用,可能正是因为不影响使用所以一直没得到修复(也有可能别人根本不觉得 ...

随机推荐

  1. mac 安装注册Charles

    软件去官网下载安装即可. 下载地址:https://www.charlesproxy.com/download/ 适用于Charles任意版本的注册码Charles 4.2.7 目前是最新版,可用. ...

  2. 实现mysql的读写分离(mysql-proxy)____1(mysql的主从复制,基于gtid的主从复制,半同步复制,组复制)

    主从复制原理: 从库生成两个线程,一个I/O线程,一个SQL线程: i/o线程去请求主库 的binlog,并将得到的binlog日志写到relay log(中继日志) 文件中:主库会生成一个 log ...

  3. Spring 中的事件机制

    说到事件机制,可能脑海中最先浮现的就是日常使用的各种 listener,listener去监听事件源,如果被监听的事件有变化就会通知listener,从而针对变化做相应的动作.这些listener是怎 ...

  4. RNN 一对一

    https://blog.csdn.net/owenfy/article/details/80022586

  5. 【深入学习linux】CentOS 7 最小化安装后的注意事项及一些必备组件的安装

    转载:https://blog.csdn.net/F_Srion/article/details/54910943 在VM虚拟机中安装CentOS 7 时 有时候顾虑到电脑硬件性能,我们需要最小化安装 ...

  6. Spring Boot-Error:(3, 32) java: 程序包org.springframework.boot不存在

    问题分析 -由于加载的项目没有加载相应的依赖的包文件导致 解决方案 setting 选中图中的设置,点击apply,IDE就会自动下载所需要的包文件

  7. weui.js汉字乱码

    2019-6-25 11:04:13 星期二 min.js 源文件中会自带乱码: 鍙栨秷:  取消; 纭畾:   确定; 方案: 把weui.js用notepad++打开, 搜索乱码字符, 替换掉, ...

  8. linux安装redis时报collect2: fatal error: cannot find 'ld'和In file included from adlist.c:34:0:

    如题,看了下该ld命令所在文件: [root@centos redis-]# whereis ld ld: /usr/bin/ld.gold /usr/bin/ld /usr/bin/ld.bfd / ...

  9. 【错误解决】git报错:you are not allowed to push code to protected branches on this project

    场景回忆: 本地修改需要退回到之前的版本,打算强制push本地版本覆盖远程版本,但是在git push --force后出现了以下的错误: Fix GitLab error: "you ar ...

  10. java html实体转义

    public static void main(String[] args) { String str = " -<->-&-"-&apos;" ...