翻譯|使用教程|編輯:龔雪|2024-09-18 10:10:47.667|閱讀 96 次
概述:本文主要介紹如何將DevExpress WinForms數(shù)據(jù)網(wǎng)格連接到由EF Core提供支持的任意ASP. NET Core WebAPI服務(wù)中,歡迎下載最新版本體驗(yàn)!
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
日前DevExpress官方發(fā)布了DevExpress WinForms的后續(xù)版本——將.NET桌面客戶端連接到安全后端Web API服務(wù)(EF Core with OData),在本文中我們將進(jìn)一步演示如何使用一個更簡單的服務(wù)來設(shè)置DevExpress WinForms數(shù)據(jù)網(wǎng)格。
P.S:DevExpress WinForms擁有180+組件和UI庫,能為Windows Forms平臺創(chuàng)建具有影響力的業(yè)務(wù)解決方案。DevExpress WinForms能完美構(gòu)建流暢、美觀且易于使用的應(yīng)用程序,無論是Office風(fēng)格的界面,還是分析處理大批量的業(yè)務(wù)數(shù)據(jù),它都能輕松勝任!
DevExpress技術(shù)交流群10:532598169 歡迎一起進(jìn)群討論
隨著時間的推移,許多最初作為桌面應(yīng)用程序的應(yīng)用程序系統(tǒng)已經(jīng)擴(kuò)展為獨(dú)立于任何原始客戶端直接綁定模式的數(shù)據(jù)訪問服務(wù)。例如,web應(yīng)用程序或移動前端可能在某個時候進(jìn)入了人們的視野,這就需要更廣泛地看待數(shù)據(jù)訪問架構(gòu)。另一方面,也許您的應(yīng)用程序系統(tǒng)還沒有經(jīng)過這些步驟!
無論哪種情況,其想法都是將直接連接轉(zhuǎn)移到數(shù)據(jù)庫服務(wù)器,例如使用Microsoft SQL Server的端口1433,轉(zhuǎn)移到不再由桌面應(yīng)用程序負(fù)責(zé)的地方。一旦您的系統(tǒng)有多個客戶端,這可能是出于維護(hù)原因的需求,或者可能是為了促進(jìn)更清晰的體系結(jié)構(gòu)。
出于本文演示的目的,數(shù)據(jù)服務(wù)將非常簡單。我們假設(shè)它使用Entity Framework Core(實(shí)體框架核心)進(jìn)行數(shù)據(jù)訪問,但關(guān)鍵是數(shù)據(jù)訪問在服務(wù)級別上不應(yīng)該是困難的。同樣,我們假設(shè)在需要的時候給服務(wù)添加功能是很容易的——當(dāng)然在這篇文章中,我們還不會關(guān)注服務(wù)不能被觸及的復(fù)雜場景。
我們做出的最后一個假設(shè)是,該服務(wù)比Odata的服務(wù)更“通用”。這并不是說使用OData不好,但是對于這個演示,我們將不使用它。
您可以在中找到這個演示的示例代碼,自述文件描述了如何運(yùn)行示例。
后端項目稱為DataService,它是使用標(biāo)準(zhǔn)ASP. NET Core WebAPI模板創(chuàng)建的,使用頂級語句和服務(wù)的“minimal API” 配置格式,它不包含本演示所不需要的任何內(nèi)容——這樣您就可以專注于演示設(shè)置本身所需的代碼。服務(wù)中有兩個端點(diǎn)處理程序,一個用于生成一些測試數(shù)據(jù),另一個用于查詢數(shù)據(jù)。
第二個處理程序位于URL /data/OrderItems,這是本文的重要處理程序。對于示例實(shí)現(xiàn),處理程序接受幾個可選參數(shù)來支持跳過、獲取和排序功能。代碼很簡單,它從Entity Framework Core數(shù)據(jù)庫上下文查詢數(shù)據(jù),并使用標(biāo)準(zhǔn)的基于IQueryable<T>的助手來實(shí)現(xiàn)數(shù)據(jù)整形功能。TotalCount字段與數(shù)據(jù)一起返回,因?yàn)槲覀冊诳蛻舳诵枰@個字段來確定有多少數(shù)據(jù)可供查詢。
app.MapGet("/data/OrderItems", async ( DataServiceDbContext dbContext, int skip = 0, int take = 20, string sortField = "Id", bool sortAscending = true) => { var source = dbContext.OrderItems.AsQueryable() .OrderBy(sortField + (sortAscending ? " ascending" : " descending")); var items = await source.Skip(skip).Take(take).ToListAsync(); var totalCount = await dbContext.OrderItems.CountAsync(); return Results.Ok(new { Items = items, TotalCount = totalCount }); });
說得更抽象一點(diǎn):這個端點(diǎn)處理程序舉例說明了數(shù)據(jù)服務(wù)中需要的服務(wù)功能,以便向前端應(yīng)用程序或?qū)S媒M件(如data Grid)提供所需的信息。實(shí)現(xiàn)和支持的數(shù)據(jù)整形特性集各不相同,但從邏輯上講,任何數(shù)據(jù)訪問都需要一些沿著這些路線工作的端點(diǎn)。
在項目WinForms.Client中,您將找到OrderItem類,這是客戶端使用的類型,表示后端上的數(shù)據(jù)。但是請注意,此類型與后端使用的類型不同,如果將其與DataService中的OrderItem仔細(xì)比較,您會發(fā)現(xiàn)前端類型與后端類型顯示的實(shí)體框架核心構(gòu)件不同,特別是在前端類型的屬性聲明中沒有virtual關(guān)鍵字。
在實(shí)際的應(yīng)用程序中,這些類型可能(很可能)差別更大。示例設(shè)置很簡單,引入數(shù)據(jù)類型只是為了演示,但實(shí)際上后端持久類型和服務(wù)檢索數(shù)據(jù)的前端模型之間的差異可能要明顯得多。
在Windows Forms應(yīng)用程序的MainForm中,DevExpress GridControl組件配置了與OrderItem的屬性相對應(yīng)的列。該組件被綁定到表單上的實(shí)例,該實(shí)例的RowType屬性被設(shè)置為OrderItem,這允許網(wǎng)格自動從數(shù)據(jù)源發(fā)現(xiàn)列。
為了獲取數(shù)據(jù),VirtualServerModeSource至少使用兩個事件處理程序(盡管根據(jù)具體情況,其中一個是可選的),ConfigurationChanged和MoreRows事件處理程序的代碼可以在MainForm.cs中找到。
當(dāng)網(wǎng)格作為對用戶交互的反應(yīng)而改變其運(yùn)行時配置的某些相關(guān)部分時,例如當(dāng)用戶單擊列標(biāo)頭應(yīng)用排序時,執(zhí)行ConfigurationChanged處理程序。當(dāng)初始獲取操作返回一個結(jié)果,表明有更多的數(shù)據(jù)可用時,MoreRows處理程序就會出現(xiàn)。在這種情況下,當(dāng)用戶滾動到當(dāng)前加載的數(shù)據(jù)集的底部時,網(wǎng)格將嘗試檢索更多的行。
在示例中,虛擬數(shù)據(jù)源的加載邏輯封裝在類VirtualServerModeDataLoader中,該類由ConfigurationChanged事件處理程序?qū)嵗丛谧罱K用戶每次更改網(wǎng)格的運(yùn)行時配置時實(shí)例化。加載器類在實(shí)例化時接收當(dāng)前配置,作為示例,代碼顯示了如何提取排序細(xì)節(jié)并記住它們以供以后的應(yīng)用程序使用。
public VirtualServerModeDataLoader( VirtualServerModeConfigurationInfo configurationInfo) { // For instance, let's assume the backend supports sorting for just one field if (configurationInfo.SortInfo?.Length > 0) { SortField = configurationInfo.SortInfo[0].SortPropertyName; SortAscending = !configurationInfo.SortInfo[0].IsDesc; } } public string SortField { get; set; } = "Id"; public bool SortAscending { get; set; } = true;
在示例中,從后端加載的數(shù)據(jù)被編碼為JSON,盡管gRPC/Protocol Buffers等不同的編碼也同樣有效。DataFetchResult類型為后端端點(diǎn)發(fā)布的結(jié)構(gòu)建模,包括TotalCount信息字段。
public class DataFetchResult { public List<OrderItem> Items { get; set; } = null!; public int TotalCount { get; set; } }
最后,GetRowsAsync方法處理實(shí)際的數(shù)據(jù)檢索。它在初始加載(從ConfigurationChanged處理程序)和進(jìn)一步加載(從MoreRows處理程序)時都被調(diào)用,但區(qū)別只是這些應(yīng)用程序之間事件參數(shù)的CurrentRowCount字段不同。
HttpClient用于檢索數(shù)據(jù),將參數(shù)作為skip、take和排序?qū)傩缘腢RL參數(shù)傳遞。結(jié)果從JSON中反序列化,并與moreRowsAvailable標(biāo)志一起返回,該標(biāo)志由網(wǎng)格解釋,如前所述。
public Task<VirtualServerModeRowsTaskResult> GetRowsAsync(VirtualServerModeRowsEventArgs e) { return Task.Run(async () => { using var client = new HttpClient(); var response = await client.GetAsync( $"{System.Configuration.ConfigurationManager.AppSettings["baseUrl"]}/data/OrderItems?skip={e.CurrentRowCount}&take={BatchSize}&sortField={SortField}&sortAscending={SortAscending}"); response.EnsureSuccessStatusCode(); var responseBody = await response.Content.ReadAsStringAsync(); var dataFetchResult = JsonSerializer.Deserialize<DataFetchResult>( responseBody, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); if (dataFetchResult is null) return new VirtualServerModeRowsTaskResult(); var moreRowsAvailable = e.CurrentRowCount + dataFetchResult.Items.Count < dataFetchResult.TotalCount; return new VirtualServerModeRowsTaskResult( dataFetchResult.Items, moreRowsAvailable); }, e.CancellationToken); }
這就完成了將數(shù)據(jù)網(wǎng)格綁定到獨(dú)立服務(wù)的第一個實(shí)現(xiàn)。
更多產(chǎn)品需求,歡迎咨詢“”~
更多DevExpress線上公開課、中文教程資訊請上中文網(wǎng)獲取
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自:慧都網(wǎng)