翻譯|使用教程|編輯:龔雪|2024-09-18 10:10:47.667|閱讀 105 次
概述:本文主要介紹如何將DevExpress WinForms數據網格連接到由EF Core提供支持的任意ASP. NET Core WebAPI服務中,歡迎下載最新版本體驗!
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
日前DevExpress官方發布了DevExpress WinForms的后續版本——將.NET桌面客戶端連接到安全后端Web API服務(EF Core with OData),在本文中我們將進一步演示如何使用一個更簡單的服務來設置DevExpress WinForms數據網格。
P.S:DevExpress WinForms擁有180+組件和UI庫,能為Windows Forms平臺創建具有影響力的業務解決方案。DevExpress WinForms能完美構建流暢、美觀且易于使用的應用程序,無論是Office風格的界面,還是分析處理大批量的業務數據,它都能輕松勝任!
DevExpress技術交流群10:532598169 歡迎一起進群討論
隨著時間的推移,許多最初作為桌面應用程序的應用程序系統已經擴展為獨立于任何原始客戶端直接綁定模式的數據訪問服務。例如,web應用程序或移動前端可能在某個時候進入了人們的視野,這就需要更廣泛地看待數據訪問架構。另一方面,也許您的應用程序系統還沒有經過這些步驟!
無論哪種情況,其想法都是將直接連接轉移到數據庫服務器,例如使用Microsoft SQL Server的端口1433,轉移到不再由桌面應用程序負責的地方。一旦您的系統有多個客戶端,這可能是出于維護原因的需求,或者可能是為了促進更清晰的體系結構。
出于本文演示的目的,數據服務將非常簡單。我們假設它使用Entity Framework Core(實體框架核心)進行數據訪問,但關鍵是數據訪問在服務級別上不應該是困難的。同樣,我們假設在需要的時候給服務添加功能是很容易的——當然在這篇文章中,我們還不會關注服務不能被觸及的復雜場景。
我們做出的最后一個假設是,該服務比Odata的服務更“通用”。這并不是說使用OData不好,但是對于這個演示,我們將不使用它。
您可以在中找到這個演示的示例代碼,自述文件描述了如何運行示例。
后端項目稱為DataService,它是使用標準ASP. NET Core WebAPI模板創建的,使用頂級語句和服務的“minimal API” 配置格式,它不包含本演示所不需要的任何內容——這樣您就可以專注于演示設置本身所需的代碼。服務中有兩個端點處理程序,一個用于生成一些測試數據,另一個用于查詢數據。
第二個處理程序位于URL /data/OrderItems,這是本文的重要處理程序。對于示例實現,處理程序接受幾個可選參數來支持跳過、獲取和排序功能。代碼很簡單,它從Entity Framework Core數據庫上下文查詢數據,并使用標準的基于IQueryable<T>的助手來實現數據整形功能。TotalCount字段與數據一起返回,因為我們在客戶端需要這個字段來確定有多少數據可供查詢。
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
});
});
說得更抽象一點:這個端點處理程序舉例說明了數據服務中需要的服務功能,以便向前端應用程序或專用組件(如data Grid)提供所需的信息。實現和支持的數據整形特性集各不相同,但從邏輯上講,任何數據訪問都需要一些沿著這些路線工作的端點。
在項目WinForms.Client中,您將找到OrderItem類,這是客戶端使用的類型,表示后端上的數據。但是請注意,此類型與后端使用的類型不同,如果將其與DataService中的OrderItem仔細比較,您會發現前端類型與后端類型顯示的實體框架核心構件不同,特別是在前端類型的屬性聲明中沒有virtual關鍵字。
在實際的應用程序中,這些類型可能(很可能)差別更大。示例設置很簡單,引入數據類型只是為了演示,但實際上后端持久類型和服務檢索數據的前端模型之間的差異可能要明顯得多。
在Windows Forms應用程序的MainForm中,DevExpress GridControl組件配置了與OrderItem的屬性相對應的列。該組件被綁定到表單上的實例,該實例的RowType屬性被設置為OrderItem,這允許網格自動從數據源發現列。
為了獲取數據,VirtualServerModeSource至少使用兩個事件處理程序(盡管根據具體情況,其中一個是可選的),ConfigurationChanged和MoreRows事件處理程序的代碼可以在MainForm.cs中找到。
當網格作為對用戶交互的反應而改變其運行時配置的某些相關部分時,例如當用戶單擊列標頭應用排序時,執行ConfigurationChanged處理程序。當初始獲取操作返回一個結果,表明有更多的數據可用時,MoreRows處理程序就會出現。在這種情況下,當用戶滾動到當前加載的數據集的底部時,網格將嘗試檢索更多的行。
在示例中,虛擬數據源的加載邏輯封裝在類VirtualServerModeDataLoader中,該類由ConfigurationChanged事件處理程序實例化,即在最終用戶每次更改網格的運行時配置時實例化。加載器類在實例化時接收當前配置,作為示例,代碼顯示了如何提取排序細節并記住它們以供以后的應用程序使用。
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;
在示例中,從后端加載的數據被編碼為JSON,盡管gRPC/Protocol Buffers等不同的編碼也同樣有效。DataFetchResult類型為后端端點發布的結構建模,包括TotalCount信息字段。
public class DataFetchResult
{
public List<OrderItem> Items { get; set; } = null!;
public int TotalCount { get; set; }
}
最后,GetRowsAsync方法處理實際的數據檢索。它在初始加載(從ConfigurationChanged處理程序)和進一步加載(從MoreRows處理程序)時都被調用,但區別只是這些應用程序之間事件參數的CurrentRowCount字段不同。
HttpClient用于檢索數據,將參數作為skip、take和排序屬性的URL參數傳遞。結果從JSON中反序列化,并與moreRowsAvailable標志一起返回,該標志由網格解釋,如前所述。
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);
}
這就完成了將數據網格綁定到獨立服務的第一個實現。
更多產品需求,歡迎咨詢“”~
更多DevExpress線上公開課、中文教程資訊請上中文網獲取
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@ke049m.cn
文章轉載自:慧都網