XAF 屬性編輯器(PropertyEditor)- 原理篇

来源:https://www.cnblogs.com/haoxj/p/18255657
-Advertisement-
Play Games

前言 隨著 DEV24.1.3 的發佈,XAF Blazor 中的屬性編輯器(PropertyEditor)也進行了很大的改動,在使用體驗上也更接近 WinForm 了,由於進行了大量的封裝,理解上沒有 WinForm 直觀,所以本文通過對屬性編輯器的原理進行解析,並對比新舊版本中的變化,使大家能夠 ...


前言

隨著 DEV24.1.3 的發佈,XAF Blazor 中的屬性編輯器(PropertyEditor)也進行了很大的改動,在使用體驗上也更接近 WinForm 了,由於進行了大量的封裝,理解上沒有 WinForm 直觀,所以本文通過對屬性編輯器的原理進行解析,並對比新舊版本中的變化,使大家能夠對屬性編輯器有一個更全面的認識。

原理

XAF 可以創建與平臺無關的業務代碼,而 PropertyEditor 就是它們與各個平臺之間的一個橋梁,也就是說 PropertyEditor 每個平臺都有各自的實現。從錶面上看 PropertyEditor 的原理並不複雜,BO 中屬性的更改會觸發 PropertyEditor 中值的更改,而 PropertyEditor 值的更改又會更新具體平臺組件的值,反過來也是一樣,組件值的更改會觸發 PropertyEditor 值的更改,而PropertyEditor 值的更改又會更新 BO 中的屬性值。

如果我們使用的是XPO,PersistentBase 是全部 BO 的基類,它實施一個 INotifyPropertyChanged 介面,我們可以通過 INotifyPropertyChanged 介面來監聽每一個屬性的變化,這樣我們就可以在屬性值發生變化時通知 PropertyEditor,而這個監聽工作是在 DetailView 中完成的。DetailView 在監聽到 BO 中屬性值發生更改時,會查找到具體的 PropertyEditor,並調用它的 Refresh 方法。

PropertyEditor 的屬性(如:Caption,DisplayFormat)大部分來自 XAF 的 Model,也就是在 PropertyEditor 初始化時會傳遞一個 IModelMemberViewItem 對象,它裡面包含了我們在模型編輯器中設置的值或一些預設值。

PropertyEditor 中有兩個比較重要的方法 ReadValue 與 WriteValue,我一開始看到這個兩方法時也產生了混淆,ReadValue 與 WriteValue 它們針對的對象是 BO 中的屬性,而不是 PropertyEditor,也就是說 ReadValue 是讀取 BO 中屬性的值,而 WriteValue 是將值寫入到屬性中。

PropertyEditor 中還有一個 Control 屬性,它的類型是 Object,不同的平臺它返回的類型是不一樣的,這個也是各個平臺的組件,WinForm 返回的是 Control 類型,Blazor 返回的是 ComponentAdapter 或 ComponentModel (24.1.3之後 XAF 自帶編輯器預設返回類型)。由於不同的平臺渲染方式不同,對於 WinForm 來說,它返回的是 Control 類型,可以直接將其放置到父組件的 Controls 中,而對於 Blazor 就不行,Blazor 組件就不能像 WinForm 控制項那樣操作,它是通過 RenderFragment 進行組合在一起的,所以 Blazor 中的 PropertyEditor 同時還實施了一個 IComponentContentHolder 介面,通過它可以返回一個 RenderFragment。

在對外暴露組件時,Blazor 比 WinForm 要多一步,Blazor 中的 RenderFragment 是用於渲染組件的,不能通過 Control 屬性返回,同時我們也無法直接操作 RenderFragment,我們是通過 ComponentModel 間接操作 Blazor 組件渲染的,所以當我們在外部想自定義 PropertyEditor 中的組件時,WinForm 是直接操作 Control,而 Blazor 是通過 ComponentModel 來完成。

PropertyEditor 的大部分子類都是圍繞上面提到的屬性或方法進行封裝,以適應不同的平臺。對於 WinForm 來說相對比較簡單,就是直接操作 Control,而對於 Blazor 來說就要繁瑣一些,就因為這樣 XAF 針對 Blazor PropertyEditor 創建,做了大量的封裝,特別是在最新的24.1.3中丟棄了 ComponentAdapter,使 PropertyEditor 的創建更加簡單,甚至比 WinForm 還要簡潔一些。下麵主要以 Blazor 為主介紹 PropertyEditor 的相關技術點。

由於本文講的是 PropertyEditor 的原理,預設讀者是熟悉 PropertyEditor 的創建,所以不會再去講解 PropertyEditor 的創建過程,而是只講解它的技術點,如果對 PropertyEditor 的創建不熟悉的小伙伴,可以查看 XAF 的官方文檔。

在 XAF 新版本中 ComponentAdapter 被廢棄了,那它被引入的原因及被廢棄的原因是什麼呢?在 XAF Blazor 創建之初 ComponentAdapter 就已存在,通過它的名字我們知道它是一個代理層,負責 PropertyEditor 與 ComponentModel 之間的通訊。那為什麼要加入這個代理層呢,而不是 PropertyEditor 直接操作 ComponentModel 呢。這裡主要考慮是 PropertyEditor 的封裝,由於 PropertyEditor 的操作基本是固定的(如,讀值、寫值及一些常規屬性的設置),而 ComponentModel 是針對不同的組件的,不同的組件會有不同的屬性,比如類似值屬性,文本框是Text,日期框是Date,數值框是Value等,通過 ComponentAdapter 來適配不同的 ComponentModel(如:GetValue,SetValue 等),PropertyEditor 再去操作 ComponentAdapter ,這樣更利於 PropertyEditor 的封裝。

那在新版本中為什麼 ComponentAdapter 又被廢棄了呢,通過 XAF 的博客可以瞭解到,由於增加了 ComponentAdapter,使創建自定義 PropertyEditor 變的比較繁瑣,移除 ComponentAdapter 後,可以使 PropertyEditor 的創建更接近於 WinForm。在沒有了 ComponentAdapter 後,是不是 PropertyEditor 直接操作 ComponentModel 了呢,如果是那樣的話,就會出現前面所講到的,這會增加自定義 PropertyEditor 的複雜度,那新版是如何實現的呢。新版中是通過介面的方式來替代 ComponentAdapter,如新版中增加了一個 IHandleValueComponentModel 介面,通過這個介面 PropertyEditor 就可以獲取、更新或監聽組件值的變化,同時又增加了 DxComponentModelBase 這樣的一個基類,它包含了一些常用的屬性。也就是說新版是通過增加不同的介面及擴展基類的方式來替代 ComponentAdapter,這樣在簡化自定義 PropertyEditor 的同時,也保持了 PropertyEditor 的靈活性。

ComponentModel 在新版中還增加了一個 ComponentType 屬性,XAF 通過 ComponentType 屬性,可以自動完成 Renderer 的創建及屬性的賦值。在之前的版本中我們都是在 Renderer 中創建一個 Create 靜態方法,將 ComponentModel 傳遞進去,Renderer 需要將 ComponentModel 中的屬性一一賦值給組件,這個過程非常繁瑣,特別是 XAF 自身的 Renderer,代碼量非常的大。新版中通過 ComponentType 的組件類型實現組件自動創建的同時,還將 ComponentModel 的屬性自動傳遞給組件(提示:ComponentModel 的屬性要與組件的屬性保持一致)。由於 XAF 中的 PropertyEditor 都是對 Blazor 組件的封裝,在 XAF 中直接省掉了 Renderer,也就是在 XAF 中沒有 Renderer 的相關代碼了。

在新版中創建一個 Blazor PropertyEditor 則相當簡單,首先創建一個繼承自 DxComponentModelBase 的 ComponentModel,在 ComponentModel 中增加組件所需要的屬性,如果是自定義組件需要創建一個 Renderer,如果是 DEV 自身的 Blazor 組件,則直接將組件賦值給 ComponentType,同時基於 BlazorPropertyEditorBase 再創建一個 PropertyEditor,重寫 CreateComponentModel 方法,並返回 ComponentModel 實例,整個 PropertyEditor 創建過程就結束了,相對來說要比 WinForm 還要簡潔一些。

總結

在日常的 XAF 開發中,不管是增強或是個性化定製,都離不開 PropertyEditor,簡化 PropertyEditor 的創建過程,在降低創建 PropertyEditor 難度的同時,也能大幅提高自定義 PropertyEditor 在項目中的占比,提高用戶操作體驗。

https://www.cnblogs.com/haoxj/p/18255657


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 官網:Git for Windows 點擊下載安裝。 右擊滑鼠會出現GUI和Bash 選擇git bash here 配置全局用戶名和郵箱(gitee) git config --global user.name "你的名字" git config --global user.email 你的郵箱 ...
  • C# 13 即 .Net 9 按照計劃會在2024年11月發佈,目前一些新特性已經定型,今天讓我們來預覽一個比較大型比較重要的新特性: 擴展類型 extension types ...
  • 目錄前言學習參考過程總結: 前言 做個自由仔。 學習參考 ChatGpt; https://www.cnblogs.com/zhili/p/DesignPatternSummery.html(大佬的,看了好多次) 過程 原由: 一開始只是想查查鏈式調用原理,以為是要繼承什麼介面,實現什麼方法才可以實 ...
  • 一:背景 1. 講故事 在dump分析的過程中經常會看到很多線程卡在Monitor.Wait方法上,曾經也有不少人問我為什麼用 !syncblk 看不到 Monitor.Wait 上的鎖信息,剛好昨天有時間我就來研究一下。 二:Monitor.Wait 底層怎麼玩的 1. 案例演示 為了方便講述,先 ...
  • 在以前我做程式的時候,一般在登錄視窗裡面顯示程式名稱,登錄視窗一般設置一張背景圖片,由於程式的名稱一般都是確定的,所以也不存在太大的問題,不過如果客戶定製不同的系統的時候,需要使用Photoshop修改下圖層的文字,再生成圖片,然後替換一下也可以了。不過本著減少客戶使用繁瑣性,也可以使用空白名稱的通... ...
  • .Net 中提供了一系列的管理對象集合的類型,數組、可變列表、字典等。從類型安全上集合分為兩類,泛型集合 和 非泛型集合,傳統的非泛型集合存儲為Object,需要類型轉。而泛型集合提供了更好的性能、編譯時類型安全,推薦使用。 ...
  • 今天在技術群里,石頭哥向大家提了個問題:"如何在一個以System身份運行的.NET程式(Windows Services)中,以其它活動的用戶身份啟動可互動式進程(桌面應用程式、控制台程式、等帶有UI和互動式體驗的程式)"? 我以前有過類似的需求,是在GitLab流水線中運行帶有UI的自動化測試程 ...
  • OPC基金會提供了OPC UA .NET標準庫以及示常式序,但官方文檔過於簡單,光看官方文檔和示常式序很難弄懂OPC UA .NET標準庫怎麼用,花了不少時間摸索才略微弄懂如何使用,以下記錄如何從一個控制台程式開發一個OPC UA伺服器。 安裝Nuget包 安裝OPCFoundation.NetSt ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...