翻譯|使用教程|編輯:龔雪|2025-06-18 11:26:54.460|閱讀 95 次
概述:本文將為大家介紹如何在Telerik UI for WinForms應用中使用Kendo UI for Angular組件來交換通信和事件,歡迎下載新版組件體驗!
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
Telerik DevCraft包含一個完整的產品棧來構建您下一個Web、移動和桌面應用程序。它使用HTML和每個.NET平臺的UI庫,加快開發速度。Telerik DevCraft提供完整的工具箱,用于構建現代和面向未來的業務應用程序,目前提供UI for ASP.NET MVC、Kendo UI、UI for ASP.NET AJAX、UI for WPF、UI for Xamarin、Reporting等眾多控件。
在這篇文章中,我們將演示如何在Telerik UI for WinForms應用程序中使用Kendo UI for Angular組件。您將了解其中的陷阱,以及如何從WinForms實現與Angular的通信,并從Angular獲取事件。
Telerik_KendoUI技術交流群(QQ):726377843
有幾種情況可以應用此方法:
這些來自遺留應用程序的轉換場景可以幫助您在開發新的服務/應用程序時使用激活的生產資源,混合解決方案可以保留當前的WinForms,同時授權開發人員構建客戶端應用程序。
在上文中(),我們為大家介紹了Kendo UI for Angular組件在WinForms應用中的深度嵌入的一些入門指南,本文將繼續介紹如何配置WinForms應用,請繼續關注喲~
在WinForms應用程序中,我將主機組件WebView2隔離在一個用戶控件AngularWebControl上。因此,所有組件都具有相同的UserControl基礎并共享相同的操作。
WebView2是必需的,它可以從URL中保存Angular應用程序,并與WinForms交互。
這是C#項目中的解決方案文件,看起來像這樣:
AngularDefs.cs將Angular項目的定義放在一個地方。這也可以是環境變量,以避免硬編碼數據:
1. namespace app_winforsm; 2. internal static class AngularDefs 3. { 4. // URL of the Angular application 5. public const string Url = "http://aw.jsmotta.com/"; 6. 7. // Route to the graph component 8. public const string RouteGraph = "graph-control"; 9. 10. // Verb to receive data in the Angular component 11. public const string ChartVerb = "receiveData"; 12. }
AngularWebControl.cs保存著接口的任務,我們在下面的代碼中添加了一些解釋。它定義組件的接口,讀取click事件,并將其傳遞給事件處理程序。
1. using Microsoft.Web.WebView2.Core; 2. using Microsoft.Web.WebView2.WinForms; 3. using System.Text.Json; 4. using Telerik.WinControls.UI; 5. 6. namespace app_winforsm; 7. internal partial class AngularWebControl : UserControl 8. { 9. // WebView Control 10. private WebView2? _webView; 11. 12. // Event to handle chart item click - it could be only OnItemClick 13. public event EventHandler? OnChartItemClick; 14. 15. // The data to be passed to the Angular component 16. private dynamic? Data { get; set; } 17. 18. // a label to show the title of the control 19. // in a real-world scenario, we can extend this component and add other controls 20. private RadLabel? Title { get; set; } 21. 22. public AngularWebControl() 23. { 24. InitializeComponent(); 25. } 26. public async void LoadData(string title, dynamic data) 27. { 28. if (Title == null) 29. { 30. Title = new RadLabel 31. { 32. Text = title, 33. Dock = DockStyle.Top, 34. Width = this.Width, 35. AutoSize = true, 36. Font = new Font("Arial", 12, FontStyle.Bold), 37. ThemeName = "Windows11" 38. }; 39. 40. 41. this.Controls.Add(Title); 42. 43. Title.MouseUp += Title_MouseUp; 44. } 45. 46. this.Title.Text = title; 47. 48. if (_webView == null) 49. { 50. _webView = new WebView2 51. { 52. Visible = true, 53. Dock = DockStyle.Fill 54. }; 55. 56. this.Controls.Add(_webView); 57. 58. var userDataFolder1 = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), $"AngularWinFormsApp_{this.Name}"); 59. 60. var environment1 = await CoreWebView2Environment.CreateAsync(userDataFolder: userDataFolder1); 61. 62. // The environment is created to avoid loss of data in the session 63. await _webView.EnsureCoreWebView2Async(environment1); 64. 65. 66. _webView.CoreWebView2.NavigationCompleted += WebView_NavigationCompleted; 67. 68. // Event to receive data from Angular 69. _webView.CoreWebView2.WebMessageReceived += CoreWebView2_WebMessageReceived; 70. 71. _webView.CoreWebView2.Navigate($"{AngularDefs.Url}{AngularDefs.RouteGraph}"); 72. 73. if (OnChartItemClick != null) 74. { 75. // This is the trick to receive data from the Angular component 76. await _webView.CoreWebView2.ExecuteScriptAsync(@" 77. window.addEventListener('MyClick', function(event) { 78. window.chrome.webview.postMessage(event.detail.message); 79. }); 80. "); 81. } 82. } 83. 84. // Send the data to the Angular component 85. this.Data = data; 86. } 87. 88. private void Title_MouseUp(object? sender, MouseEventArgs e) 89. { 90. if (e.Button == MouseButtons.Right) 91. { 92. // An easter egg to show the WebView console 93. // when pressing right click on the RadLabel 94. ShowWebViewConsole(); 95. } 96. } 97. 98. // Event handler to handle messages received from the WebView2 99. private void CoreWebView2_WebMessageReceived(object? sender, CoreWebView2WebMessageReceivedEventArgs e) 100. { 101. // Retrieve the message from the event 102. var message = e.TryGetWebMessageAsString(); 103. 104. // Display the message or perform any action 105. OnChartItemClick?.Invoke(message, EventArgs.Empty); 106. } 107. private async void WebView_NavigationCompleted(object? sender, CoreWebView2NavigationCompletedEventArgs e) 108. { 109. if (_webView == null) return; 110. 111. _webView.Visible = true; 112. 113. if (!e.IsSuccess) 114. { 115. // Return a custom messsage based on the error to avoid default Webview error page 116. switch (e.WebErrorStatus) 117. { 118. 119. case CoreWebView2WebErrorStatus.ConnectionAborted: 120. ShowErrorMessage("Connection refused. Please make sure the server is running and try again."); 121. break; 122. case CoreWebView2WebErrorStatus.Unknown: 123. case CoreWebView2WebErrorStatus.CertificateCommonNameIsIncorrect: 124. case CoreWebView2WebErrorStatus.CertificateExpired: 125. case CoreWebView2WebErrorStatus.ClientCertificateContainsErrors: 126. case CoreWebView2WebErrorStatus.CertificateRevoked: 127. case CoreWebView2WebErrorStatus.CertificateIsInvalid: 128. case CoreWebView2WebErrorStatus.ServerUnreachable: 129. case CoreWebView2WebErrorStatus.Timeout: 130. case CoreWebView2WebErrorStatus.ErrorHttpInvalidServerResponse: 131. case CoreWebView2WebErrorStatus.ConnectionReset: 132. case CoreWebView2WebErrorStatus.Disconnected: 133. case CoreWebView2WebErrorStatus.CannotConnect: 134. case CoreWebView2WebErrorStatus.HostNameNotResolved: 135. case CoreWebView2WebErrorStatus.OperationCanceled: 136. case CoreWebView2WebErrorStatus.RedirectFailed: 137. case CoreWebView2WebErrorStatus.UnexpectedError: 138. case CoreWebView2WebErrorStatus.ValidAuthenticationCredentialsRequired: 139. case CoreWebView2WebErrorStatus.ValidProxyAuthenticationRequired: 140. default: 141. ShowErrorMessage("An error occurred while loading the page."); 142. break; 143. } 144. return; 145. } 146. 147. var jsonData = JsonSerializer.Serialize(Data); 148. 149. // Here is the connection with the interface (verb) defined in the Angular component 150. var script = $"window.{AngularDefs.ChartVerb}({jsonData});"; 151. 152. await _webView.CoreWebView2.ExecuteScriptAsync(script); 153. } 154. 155. }
Message.cs是Angular應用中click事件交互的模型。
下面是FormMain.cs中控件的用例,我們動態地添加了一個控件,并使用工具箱中的拖放功能添加了另一個控件。需要注意的是,需要一個不同的屬性名來避免WebView2會話上的沖突,這是一個陷阱。
在這個示例中使用模擬數據,但您可能會在實際應用程序中從數據源讀取數據。
1. using System.Text.Json; 2. using Telerik.WinControls; 3. using Telerik.WinControls.UI; 4. 5. namespace app_winforsm; 6. 7. public partial class FormMain : RadForm 8. { 9. private readonly AngularWebControl? _angularWebControl; 10. 11. public FormMain() 12. { 13. InitializeComponent(); 14. 15. // Load the AngularWebControl programatically 16. 17. _angularWebControl = new AngularWebControl { Name = "_angularWebControl" }; 18. _angularWebControl.Dock = DockStyle.Fill; 19. 20. splitPanel1.Controls.Add(_angularWebControl); 21. 22. // Subscribe to the OnChartItemClick event 23. _angularWebControl.OnChartItemClick += AngularWebControl_OnChartItemClick; 24. 25. LoadData(); 26. } 27. 28. private void AngularWebControl_OnChartItemClick(object? sender, EventArgs e) 29. { 30. if (sender is null) 31. return; 32. 33. var message = 34. JsonSerializer.Deserialize<Message>(sender.ToString() ?? throw new Exception("Data is not a json.")); 35. 36. RadMessageBox.ThemeName = "Windows11"; 37. RadMessageBox.Show($"You clicked on {message.Category} with value {message.Value}", "Chart Item Clicked", 38. MessageBoxButtons.OK, RadMessageIcon.Info); 39. } 40. 41. private void LoadData() 42. {
注意:在生產項目中,您將從存儲庫加載數據!
43. 44. var data = new[] 45. { 46. new { name = "Gastroenteritis", value = 40, color = "red" }, 47. new { name = "Appendicitis", value = 25, color = "blue" }, 48. new { name = "Cholecystitis", value = 15, color = "green" }, 49. new { name = "Pancreatitis", value = 10, color = "yellow" }, 50. new { name = "Diverticulitis", value = 10, color = "orange" } 51. }; 52. 53. _angularWebControl?.LoadData("Common gastro deseases in hospitals", data); 54. 55. var dataAges = new[] 56. { 57. new { name = "0-10", value = 1, color = "red" }, 58. new { name = "11-20", value = 10, color = "blue" }, 59. new { name = "21-30", value = 20, color = "green" }, 60. new { name = "31-40", value = 25, color = "yellow" }, 61. new { name = "41-50", value = 15, color = "orange" }, 62. new { name = "51-60", value = 20, color = "purple" }, 63. new { name = "61-70", value = 8, color = "brown" }, 64. new { name = "71+", value = 7, color = "pink" } 65. }; 66. 67. this.angularWebControl1.LoadData("Patiant ages in gastro deseases", dataAges); 68. } 69. }
這兩個圖表共享相同的界面和UserControl,它們處于不同的web會話中。會話被隔離是為了保存數據,并且出于安全考慮,同一個UserControl可以根據作為參數傳遞的URL使用不同的憑據。
在下面的圖片中,我們可以“看到”編碼的流程和執行,直到回調時,最終用戶點擊圖表,從GitHub并嘗試。
慧都是?家?業數字化解決?案公司,專注于軟件、?油與?業領域,以深?的業務理解和?業經驗,幫助企業實現智能化轉型與持續競爭優勢。
慧都科技是Telerik的中國區的合作伙伴,Telerik作為用戶界面領域的優秀產品,通過全棧式開發工具套件(涵蓋Web、桌面、移動端及報表服務)提供160+高性能UI組件、低代碼平臺及實時調試工具,助力企業快速構建跨平臺業務應用(如ERP、數據分析儀表盤),顯著縮短開發周期(降本50%以上)并提升數據處理與界面交互效率。
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自:慧都網