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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...