OnApplyTemplate 不執行
平時如何開發自定義控件的
在WPF自定義控件開發的過程中遇到了這樣一個問題,屬性更改事件在OnApplyTemplate之前執行。我在寫自定義控件的時候,喜歡通過OnApplyTempalte重寫方法獲取到Style中的所有控件,進而在屬性更改通知時修改這些控件的值。
問題
所有暴露的依賴屬性都是通過Binding來賦值的。今天的案例特殊,某個屬性不需要Binding賦值,直接給值即可,於是運行時出問題了。
未將對象引用到實例
很普通的一個錯誤,然后卻暴露了屬性更改通知先於OnApplyTemplate執行的問題。
解釋
只有看源碼,發現了這么一段代碼

注意MeasureCore這個方法,這個是發生了布局重繪重計算時會執行的,那么就是說OnApplyTemplate發生在顯示的時候,而簡單的屬性設置立馬就生效,不需要等到控件顯現出來,只要控件對象存在就能執行,這就是為什么依賴屬性直接設置的話,他的屬性更改事件會先於OnApplyTemplate執行。使用Binding的話,不會出現這個問題,因為Binding至少也要等到控件繪制完成執行才有意義。
反思
那么是不是自定義控件的兩種方式不能共存?肯定不是的,WPF官方的Button就能同時適應這兩種情況,於是再去看看Button的源碼,根本就沒有用到OnApplyTemplate方法,並且看他的Style,內容樣式綁定都是使用了TemplateBinding來完成。最后得出了結論就是:簡單的自定義樣式開發,其實都可以通過在其Style文件中使用TemplateBinding來完成。也就是自定義控件的樣式開發和后台邏輯只關注依賴屬性,不關注具體使用了什么控件。通過OnApplyTempalte方法來獲取具體控件的方法用在一些高級的自定義控件上。
記錄下來,因為網上搜半天也沒人能說清個所以然,希望能幫助到你們。
