WPF OnApplyTemplate 不执行 或者执行滞后的疑惑

OnApplyTemplate 不执行

平时如何开发自定义控件的

在WPF自定义控件开发的过程中遇到了这样一个问题,属性更改事件在OnApplyTemplate之前执行。我在写自定义控件的时候,喜欢通过OnApplyTempalte重写方法获取到Style中的所有控件,进而在属性更改通知时修改这些控件的值。

问题

所有暴露的依赖属性都是通过Binding来赋值的。今天的案例特殊,某个属性不需要Binding赋值,直接给值即可,于是运行时出问题了。

未将对象引用到实例

很普通的一个错误,然后却暴露了属性更改通知先于OnApplyTemplate执行的问题。

解释

只有看源码,发现了这么一段代码
图片
注意MeasureCore这个方法,这个是发生了布局重绘重计算时会执行的,那么就是说OnApplyTemplate发生在显示的时候,而简单的属性设置立马就生效,不需要等到控件显现出来,只要控件对象存在就能执行,这就是为什么依赖属性直接设置的话,他的属性更改事件会先于OnApplyTemplate执行。使用Binding的话,不会出现这个问题,因为Binding至少也要等到控件绘制完成执行才有意义。

反思

那么是不是自定义控件的两种方式不能共存?肯定不是的,WPF官方的Button就能同时适应这两种情况,于是再去看看Button的源码,根本就没有用到OnApplyTemplate方法,并且看他的Style,内容样式绑定都是使用了TemplateBinding来完成。最后得出了结论就是:简单的自定义样式开发,其实都可以通过在其Style文件中使用TemplateBinding来完成。也就是自定义控件的样式开发和后台逻辑只关注依赖属性,不关注具体使用了什么控件。通过OnApplyTempalte方法来获取具体控件的方法用在一些高级的自定义控件上。

记录下来,因为网上搜半天也没人能说清个所以然,希望能帮助到你们。

转载于:https://www.cnblogs.com/HelloMyWorld/p/6704403.html

在C#的WPF(Windows Presentation Foundation)框架中,如果你想要判断一个按钮的执行是否完成,你可以使用多种方法。首先,按钮事件本身是同步的,这意味着当按钮的点击事件被触发时,事件处理方法会执行完毕后才会继续执行后续的代码。通常,你可以直接在按钮的点击事件处理方法中编写需要执行的代码。 然而,如果你在点击事件中启动了一个长时间运行的操作(比如调用一个耗时的函数),并且你想要在该操作完成后执行其他操作,你可以使用异步编程技术,例如异步方法或者后台线程。在WPF中,你可以使用`async`和`await`关键字来处理异步操作。 下面是一个简单的示例,展示如何使用异步方法来处理耗时操作,并在操作完成后更新UI: ```csharp private async void Button_Click(object sender, RoutedEventArgs e) { // 启动异步操作 await LongRunningProcessAsync(); // 异步操作完成后,可以安全地更新UI // 例如,可以启用按钮或显示一个消息 button.IsEnabled = true; MessageBox.Show("操作完成!"); } private async Task LongRunningProcessAsync() { // 模拟耗时操作 await Task.Delay(5000); // 假设这是一个5秒钟的耗时操作 } ``` 在这个例子中,`LongRunningProcessAsync`方法是一个异步方法,它使用`Task.Delay`来模拟耗时操作。当点击按钮时,`Button_Click`方法会被触发,耗时操作开始。由于使用了`await`关键字,UI线程不会被阻塞,按钮在耗时操作开始后即可被重新启用,且在操作完成后会弹出一个消息框提示用户。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值