C# wpf 获取控件刷新的时机

这篇具有很好参考价值的文章主要介绍了C# wpf 获取控件刷新的时机。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

做wpf开发不像mfc控件的刷新相对同步,wpf的控件改变宽高或者可见性后在下一行代码不会立刻看到效果,而且也没有一种事件可以获取确切的界面刷新后的时机。如果只是进行延迟等待,在不同机器效果是不同的,而且也并没有具体标识说明已刷新界面,这就导致某些场景的功能实现起来会比较困难。本文提供一种获取控件真正界面刷新时机的方法。


一、为何要获取刷新时机?

例子一、隐藏控件后截屏

需要隐藏控件后截屏,直接修改Visibility后截屏是不行的,控件不会立刻隐藏,所以会截到控件的画面。如果不能获取到真正的刷新时机,那就这能延时等待,但延时是不稳定的,至少笔者就遇到了延时500毫秒再截屏,依然在生产环境有客户遇到了截到控件画面的bug。

例子二、修改控件大小后做计算

有一段逻辑需要根据控件大小做计算,使用的是ActualWidth、ActualHeight。在这段逻辑前刚好有修改大小的代码,但此时修改Width、Height之后ActualWidth、ActualHeight不会立刻改变,需要等到界面刷新时会改变,这就会导致计算数值不正确。这种场景很可能难以使用延时。


二、如何实现?

1.使用动画

wpf的动画有个完成事件,我们通过这个事件就可以获取绘制完一帧的时机。

//创建
var da = new DoubleAnimation(1, 0, new Duration(TimeSpan.FromMilliseconds(1)), FillBehavior.Stop);
da.Completed += (S, E) {
//动画完成,此处表明控件已刷新
};
//启动动画触发绘制
elememt.BeginAnimation(Control.OpacityProperty, da);

2.使用TaskCompletionSource

使用TaskCompletionSource是为了提供异步接口,方便使用,在使用时只需要await即可。

 var tcs = new TaskCompletionSource();
 da.Completed += (S, E) => tcs.SetResult();
 await tcs.Task;

三、完整代码

public static class ElementExtensions
{
    /// <summary>
    /// 等待控件真实刷新后
    /// </summary>
    internal static Task WaitForPaint(this UIElement elememt)
    {
        var tcs = new TaskCompletionSource();
        //通过动画来获取这个时机
        var da = new DoubleAnimation(1, 0, new Duration(TimeSpan.FromMilliseconds(1)), FillBehavior.Stop);
        da.Completed += (S, E) => tcs.SetResult();
        //启动动画触发绘制
        elememt.BeginAnimation(Control.OpacityProperty, da);
        return tcs.Task;
    }
}

四、使用示例

1、隐藏工具条截屏

private async void Button_Click(object sender, RoutedEventArgs e)
{   
    //隐藏工具条
    toolBar.Visibility= Visibility.Collapsed;
    //等待界面上真正隐藏
    await toolBar.WaitForPaint();
    //截屏//显示工具条
    toolBar.Visibility= Visibility.Visible;
}

2、修改宽高后获取ActualWidth、ActualHeight

private async void Button_Click(object sender, RoutedEventArgs e)
{
    var button = sender as Button;
    Console.WriteLine("ActualWidth=" + button.ActualWidth + "   ActualHeight=" + button.ActualHeight);
    button.Width = 100;
    button.Height = 100;
    Console.WriteLine("ActualWidth=" + button.ActualWidth + "   ActualHeight=" + button.ActualHeight);
    await button.WaitForPaint();
    Console.WriteLine("ActualWidth=" + button.ActualWidth + "   ActualHeight=" + button.ActualHeight);
}

效果预览
C# wpf 获取控件刷新的时机,# wpf,c#,wpf,开发语言


总结

以上就是今天要讲的内容,本文的做法是笔者曾经在某个论坛看到的建议,然后去尝试实现发现是可行的,后来进一步封装为异步方法。发出来的主要目的是作为记录,一方面是方便以后拷贝使用,另一方面也希望能对大家有所帮助。文章来源地址https://www.toymoban.com/news/detail-798173.html

到了这里,关于C# wpf 获取控件刷新的时机的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • WPF 获取父容器控件的宽度

    在WPF中,如果你想要获取一个控件的父容器(Parent)的宽度,你可以通过以下方式访问: 这里的 this 指的是当前控件实例。 .Parent 属性返回直接父容器, .ActualWidth 则是获取该父容器的实际渲染宽度。 如果你需要获取更高级别的祖先容器的宽度,或者是在代码后面绑定到某个

    2024年01月17日
    浏览(29)
  • [C# WPF] 如何给控件添加边框(Border)?

    在WPF中,可以使用边框控件或者边框属性来为控件添加边框。 以下是两种常见的方法: WPF中的Border控件用于为其他控件添加边框效果。它是一个容器控件,可以包含一个子元素,并为其提供边框、背景和填充等装饰效果。 以下是Border控件的一些主要属性: BorderBrush:用于定

    2024年02月20日
    浏览(34)
  • C# wpf 附加属性实现任意控件拖动调整大小

    第一节 Grid内控件拖动调整大小 第二节 Canvas内控件拖动调整大小 第三节 窗口拖动调整大小 第四节 附加属性实现拖动调整大小(本章) 第五章 拓展更多调整大小功能 前面几节讲了控件拖动改变大小的几种方法,根据不同的布局可以有不同的实现方式。本节主要讲的是利用

    2024年02月11日
    浏览(48)
  • C# wpf 实现任意控件(包括窗口)更多调整大小功能

    第一节 Grid内控件拖动调整大小 第二节 Canvas内控件拖动调整大小 第三节 窗口拖动调整大小 第四节 附加属性实现拖动调整大小 第五章 拓展更多调整大小功能(本章) 上一章我们已经实现了任意控件统一的拖动调整功能,能够方便的给任意控件设置拖动调整大小。开发过程

    2024年01月18日
    浏览(39)
  • 【小沐学C#】WPF中嵌入web网页控件(WebBrowser、WebView2、CefSharp)

    使用 Windows Presentation Foundation (WPF),你可以创建适用于 Windows 且具有非凡视觉效果的桌面客户端应用程序。 WPF 的核心是一个与分辨率无关且基于矢量的呈现引擎,旨在充分利用现代图形硬件。 WPF 通过一套完善的应用程序开发功能对该核心进行了扩展,这些功能包括可扩展应

    2024年02月03日
    浏览(55)
  • WPF应用开发之控件动态内容展示

    在我们开发一些复杂信息的时候,由于需要动态展示一些相关信息,因此我们需要考虑一些控件内容的动态展示,可以通过动态构建控件的方式进行显示,如动态选项卡展示不同的信息,或者动态展示一个自定义控件的内容等等,目的就是能够减少一些硬编码的处理方式,以

    2024年02月05日
    浏览(60)
  • WPF开发一个可以自适应排列的Panel控件

    一.控件介绍     初看标题可能无法理解,我们看看什么是自适应排列。 乍一看它有点像WrapPanel控件,都是从左至右排列,如果一行排列不下就换行继续排列,但是细看你就会发现不对,WrapPanel控件行尾是不会对齐的,也就是说只要WrapPanel的子控件的宽度不一致,每一行的

    2024年04月08日
    浏览(48)
  • WPF开发经验-WPF的TextBox控件的MouseDown事件不响应的解决方法

    最近项目有个需求,大概是,当点击某个TextBox时,先执行一些业务上的逻辑处理。 于是按以往思维,将TextBox的MouseDown事件关联事件处理方法,将业务处理写在方法里。 调试发现,点击TextBox时,事件处理方法未执行。 通过查阅微软官方文档了解到问题原因。 附上文档链接:

    2024年02月08日
    浏览(42)
  • MAUI 框架开发 将 MAUI 嵌入到 WPF 控件里

    本文将介绍如何将 MAUI 的底层替换为 WPF 框架层,且将 MAUI 的内容嵌入到 WPF 的一个控件里面,无 UI 框架嵌入的空域问题 本文是 MAUI 框架开发博客,而不是 MAUI 应用开发博客,本文更多介绍的是进行 MAUI 这个框架的开发内容。不熟悉或不进行 MAUI 框架开发的伙伴也可以看着玩

    2024年02月17日
    浏览(45)
  • 使用WPF开发自定义用户控件,以及实现相关自定义事件的处理

    在前面随笔《使用Winform开发自定义用户控件,以及实现相关自定义事件的处理》中介绍了Winform用户自定义控件的处理,对于Winform自定义的用户控件来说,它的呈现方式主要就是基于GDI+进行渲染的,对于数量不多的控件呈现,一般不会觉察性能有太多的问题,随着控件的数量

    2024年02月02日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包