天天看點

WPF 如何擷取有哪些 VisualBrush 用了某個控件

我寫了一個特殊的控件,我期望了解到有哪些 VisualBrush 捕獲了此控件,或者說有哪些 VisualBrush 用了此控件的界面

本文的方法需要用到反射,需要使用 WPF 架構裡面沒有公開的字段擷取某個 Visual 控件被引用的 VisualBrush 有哪些,代碼如下

通過上面代碼不僅可以擷取某個控件,是否被作為 VisualBrush 的 Visual 作為畫刷,還可以擷取目前有哪些 VisualBrush 捕獲了這個控件

寫一個簡單的界面,将這個控件設定為某個 VisualBrush 的 Visual 内容,然後将這個 VisualBrush 作為背景

在界面的構造裡面,在 InitializeComponent 方法之後,調用 IsInVisualBrush 方法,傳回的是不被 VisualBrush 捕獲。但是如果在 Loaded 事件擷取,傳回的是沒有被捕獲。隻有在 Loaded 事件加上 Dispatcher 延遲傳回的才是被捕獲

而如果在點選按鈕的時候,将使用了 VisualBrush 作為背景的 Border 移除,那麼立刻就可以擷取到沒有被捕獲

上面代碼其實用到了 WPF 的機制,在 WPF 裡面,所有的控件都繼承了 Visual 類型(無視3D部分)而在此類型裡面,将會在被 VisualBrush 使用的時候,調用 AddRefOnChannelForCyclicBrush 方法

上面的 ICyclicBrush 定義如下

所有 VisualBrush 繼承了這個接口

在設定 VisualBrush 的 Visual 屬性的時候,将會觸發 VisualPropertyChanged 函數

在這個函數裡面将會調用 VisualBrush 的 AddRefResource 方法

在 AddRefResource 函數裡面将會調用上文的具體的 Visual 的 AddRefOnChannelForCyclicBrush 方法

是以在 Visual 裡面是可以了解到目前的的對象被哪些 VisualBrush 捕獲

而在 Visual 裡面存放的字典是不開放的,需要使用本文的反射的方式才能拿到對象進而了解這個控件是否作為 VisualBrush 的内容

本文所有代碼放在 github 和 gitee 歡迎通路

可以通過如下方式擷取本文的源代碼,先建立一個空檔案夾,接着使用指令行 cd 指令進入此空檔案夾,在指令行裡面輸入以下代碼,即可擷取到本文的代碼

以上使用的是 gitee 的源,如果 gitee 不能通路,請替換為 github 的源

擷取代碼之後,進入 CalbuhewaNallrolayrani 檔案夾

參考:c# - How to know whether my control be used in VisualBrush - Stack Overflow

WPF 如何擷取有哪些 VisualBrush 用了某個控件

本作品采用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協定進行許可。歡迎轉載、使用、重新釋出,但務必保留文章署名林德熙,不得用于商業目的,基于本文修改後的作品務必以相同的許可釋出。如有任何疑問,請與我