主頁 > .NET開發 > 用WindowsAppSDK(WASDK)優雅的開發上位機應用

用WindowsAppSDK(WASDK)優雅的開發上位機應用

2022-06-29 07:28:05 .NET開發

C#開發上位機應用的一些選擇

如果你不想看介紹,可以直接跳到優雅開發示例那里,

1. WASDK(WinUI 3)

Windows 應用 SDK 是一組新的開發人員組件和工具,它們代表著 Windows 應用開發平臺的下一步發展, Windows 應用 SDK 提供一組統一的 API 和工具,可供從 Windows 11 到 Windows 10 版本 1809 上的任何桌面應用以一致的方式使用,

Windows 應用 SDK 不會用 C++ 替換 Windows SDK 或現有桌面 Windows 應用型別,例如 .NET(包括 Windows 表單和 WPF)和桌面 Win32, 相反,Windows 應用 SDK 使用一組通用 API 來補充這些現有工具和應用型別,開發人員可以在這些平臺上依賴這些 API 來執行操作, 有關更多詳細資訊,請參閱Windows 應用 SDK 的優勢,

這個WASDK目前是微軟主推的開源的,UI部分是結合了WinUI 3,

2. WPF

歡迎使用 Windows Presentation Foundation (WPF) 桌面指南,這是一個與解析度無關的 UI 框架,使用基于矢量的呈現引擎,構建用于利用現代圖形硬體, WPF 提供一套完善的應用程式開發功能,這些功能包括 Extensible Application Markup Language (XAML)、控制元件、資料系結、布局、二維和三維圖形、影片、樣式、模板、檔案、媒體、文本和版式, WPF 屬于 .NET,因此可以生成整合 .NET API 其他元素的應用程式,

目前WPF也已經開源,而且整體上更為成熟,Visual Studio就是WPF 4.x開發的,生態也比較好,

3. WinForms

歡迎使用 Windows 表單的桌面指南,Windows 表單是一個可創建適用于 Windows 的豐富桌面客戶端應用的 UI 框架, Windows 表單開發平臺支持廣泛的應用開發功能,包括控制元件、圖形、資料系結和用戶輸入, Windows 表單采用 Visual Studio 中的拖放式可視化設計器,可輕松創建 Windows 表單應用,

這個也是開源的,Winform算是上手即用的開發框架了,通過拖拉拽可以很輕松的創建出UI和撰寫對應的功能,對于UI美觀程度不太重要的工業領域,這個用來做工具開發很簡單,上手也容易,

4. UWP

UWP 是創建適用于 Windows 的客戶端應用程式的眾多方法之一, UWP 應用使用 WinRT API 來提供強大的 UI 和高級異步功能,這些功能非常適用于 Internet 連接的設備,

微軟對于UWP,只能說曾經愛過,當初UWP可是當紅炸子雞,號稱跨windows全平臺,不過現在也是跨windows全平臺,可惜沒搞好,不過雖然不夠受重視,但是一時半會還是死不掉,畢竟WASDK還不夠成熟,

為什么選擇WASDK

通過上面的介紹,大家對于windows下的原生UI開發框架應該有了一些了解,如果拋開語言限制的話還有更多的選擇,比如QT,各種前端的跨平臺,像微軟自己家的MAUI什么的,我之前還寫了一篇WinUI遷移到即將"過時"的.NET MAUI個人體驗,

最近的微軟Windows App SDK 1.1版本發布了,意味著BUG應該少了很多,也可以正式的在一些專案中使用了,通過官方的WinUI庫,我們可以輕松的構建符合Win11設計規范的UI,由于UWP的種種問題,WPF和WinForms又是只開源,應該不會有大的新特性了,外加本人以前也經常玩玩UWP,通過前景和自己的喜好,肯定是選擇WASDK了,

優雅開發示例

1. 做一個上位機應用

上位機示例圖
上圖為應用的展示圖,采用的WASDK1.1版本開發,目前已經上架了Windows商店,打包方式為MSIX,目前x64和arm64是分開的MSIX包,檔案里提到可以多個MSIX包合成一個集合包,不過我采用上傳多個包,讓商店自動匹配,

此應用是為稚暉君的ElectronBot開發的第三方的上位機,名字就叫電子腦殼,下圖是效果圖展示,結合Surface平板,觸摸體驗良好,個人感覺很優雅,

實物控制

B站演示視頻

2. 整體的開發步驟

ElectronBot本身連接電腦采用的是libusb生成的驅動吧,這個不知道敘述的是否正確,

看下圖大體能明白電腦和ElectronBot通過高速USB進行連接,當我們驅動安裝成功就可以進行操作了,

img

電子腦殼應用=>ElectronBot.DotNet SDK=>LibUsbDotNet

底層呼叫采用的是LibUsbDotNet這個庫進行底層資料傳輸的操作,我根據稚暉君提供的c++版本的sdk進行了封裝,

目前c#版本的SDKElectronBot.DotNet是開源的,demo示例也是windowsAppSDK的,大家感興趣的可以star一下,

開始創建專案前最好安裝下Template Studio for WinUI

img

2.1 創建專案

img

選擇模板進行創建,可以根據需要進行選擇,本人選擇如下,
img

由于ElectronBot .Net SDK本身已經開源,直接以上位機主體應用做講解,下圖為應用的依賴項,主要包含SDK和OpenCV相關的nuget包,

應用依賴項

應用整體不復雜,通過.Net框架自帶的DI容器進行物件生命周期的管理,通過MVVM進行資料的系結和更新,

結合Win2D和OpenCV進行圖形資料處理,然后通過SDK寫入到usb設備里進行控制和展示,

軟體整體的實作邏輯

2.2 關鍵點代碼講解

下面的代碼是通過切換Combox事件,動態創建不同的表盤并系結到MainWindows的控制元件上,

private ICommand _clockChangedCommand;
public ICommand ClockChangedCommand => 
    _clockChangedCommand ?? (_clockChangedCommand = new RelayCommand(ClockChanged));

private async void ClockChanged()
{
    var clockName = _clockComboxSelect.DataKey;

    if (!string.IsNullOrWhiteSpace(clockName))
    {
        var viewProvider = _viewProviderFactory.CreateClockViewProvider(clockName);

        Element = viewProvider.CreateClockView(clockName);
    }

    await Task.CompletedTask;
}

public UIElement Element
{
    get => _element;
    set => SetProperty(ref _element, value);
}

xaml代碼如下,

img

通過此操作,能夠正常顯示表盤,資料重繪也能正常使用,

當切換到時鐘模式的時候,另外一個定時器會定時抓取表盤并將xaml轉化成圖片進行傳輸,主要涉及到Win2D庫的使用,代碼如下,

if (_electron.Connect())
{
    var bitmap = new RenderTargetBitmap();
    await bitmap.RenderAsync(Element);
    var pixels = await bitmap.GetPixelsAsync();

    // Transfer the pixel data from XAML to Win2D for further processing.
    using CanvasDevice canvasDevice = CanvasDevice.GetSharedDevice();

    using CanvasBitmap canvasBitmap = CanvasBitmap.CreateFromBytes(
        canvasDevice, pixels.ToArray(), bitmap.PixelWidth, bitmap.PixelHeight, 
        Windows.Graphics.DirectX.DirectXPixelFormat.B8G8R8A8UIntNormalized);

    using IRandomAccessStream stream = new InMemoryRandomAccessStream();

    await canvasBitmap.SaveAsync(stream, CanvasBitmapFileFormat.Png);

    Bitmap image = new Bitmap(stream.AsStream());

    var mat = OpenCvSharp.Extensions.BitmapConverter.ToMat(image);

    var mat1 = mat.Resize(new OpenCvSharp.Size(240, 240), 0, 0, OpenCvSharp.InterpolationFlags.Area);

    var mat2 = mat1.CvtColor(OpenCvSharp.ColorConversionCodes.RGBA2BGR);

    var dataMeta = mat2.Data;

    var data = https://www.cnblogs.com/GreenShade/p/new byte[240 * 240 * 3];

    Marshal.Copy(dataMeta, data, 0, 240 * 240 * 3);

    await Task.Run(() =>
    {
        if (_electron.Connect())
        {
            _electron.SetImageSrc(data);

            _electron.Sync();
        }
    });


}

上面代碼通過RenderTargetBitmap和Win2D將Xaml元素轉化成CanvasBitmap,然后再通過OpenCV將canvasBitmap轉化成下位機可識別的位元組陣列,通過SDK進行傳輸到下位機,

整體的開發程序和UWP很相似,UI部分用到的很多API都是UWP的改名版本,上位機目前沒有開源,所以只能截取部分代碼進行講解了,如果想交流大家可以評論區見,

3. 遇到的一些問題

目前Windows App SDK有一些BUG,在我使用的程序中主要發現使用WinRT的串口監聽事件失效,已在github提了bug,回頭應該能夠修復,還有WinRT里的一些API只認UWP UI Api windows.UI開頭的一些物件,還需要大家多使用多反饋,這樣WASDK開發才能良性回圈,

public async Task InitAsync()
{
    // Target all Serial Devices present on the system
    var deviceSelector = SerialDevice.GetDeviceSelector();

    var myDevices = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(deviceSelector);

    deviceWatcher = DeviceInformation.CreateWatcher(deviceSelector);

    deviceWatcher.Added += new TypedEventHandler<DeviceWatcher, DeviceInformation>(this.OnDeviceAdded);
    deviceWatcher.Removed += new TypedEventHandler<DeviceWatcher, DeviceInformationUpdate>(this.OnDeviceRemoved);

}

上面代碼注冊的事件,在目前1.1版本的WASDK不生效,官方已經標注為BUG,當然在UWP里就正常,UWP在有些時候還是挺靠譜的嘛,

個人總結感悟

通過這個上位機應用的開發,也是對WASDK和UWP相關技術的使用能熟練一些了,從WPF到UWP再到WASDK和MAUI,XAML相關的開發都是可繼承的,開發方式很相似,對于技術的遷移來說也算是沒什么障礙吧,經常會聽到很多人說微軟出了這么多技術,都學不動了什么的,其實大家掌握內涵,對于新技術的接受還是很快的,

特別鳴謝以及參考推薦檔案

感謝dino.c大佬的一個番茄鐘,因為我的表盤其實就是抄他番茄鐘的代碼,

感謝h哥和火火給的一些思路,

當然還要感謝超超,畢竟有些代碼還是抄他的,

參考推薦檔案如下

一個番茄鐘

Win2D samples

opencvsharp

WindowsAppSDK

WindowsCommunityToolkit

ElectronBot

ElectronBot.DotNet

LibUsbDotNet

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/497004.html

標籤:.NET Core

上一篇:提交后禁用按鈕后表單未提交

下一篇:Redis 原理 - String

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • WebAPI簡介

    Web體系結構: 有三個核心:資源(resource),URL(統一資源識別符號)和表示 他們的關系是這樣的:一個資源由一個URL進行標識,HTTP客戶端使用URL定位資源,表示是從資源回傳資料,媒體型別是資源回傳的資料格式。 接下來我們說下HTTP. HTTP協議的系統是一種無狀態的方式,使用請求/ ......

    uj5u.com 2020-09-09 22:07:47 more
  • asp.net core 3.1 入口:Program.cs中的Main函式

    本文分析Program.cs 中Main()函式中代碼的運行順序分析asp.net core程式的啟動,重點不是剖析原始碼,而是理清程式開始時執行的順序。到呼叫了哪些實體,哪些法方。asp.net core 3.1 的程式入口在專案Program.cs檔案里,如下。ususing System; us ......

    uj5u.com 2020-09-09 22:07:49 more
  • asp.net網站作為websocket服務端的應用該如何寫

    最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與服務器建立連接,然后服務器根據ip給客戶端網頁發送資訊。 其實,這個需求并不難,只是剛開始對websocket的內容不太了解。上網搜索了一下,有通過asp.net core 實作的、有 ......

    uj5u.com 2020-09-09 22:08:02 more
  • ASP.NET 開源匯入匯出庫Magicodes.IE Docker中使用

    Magicodes.IE在Docker中使用 更新歷史 2019.02.13 【Nuget】版本更新到2.0.2 【匯入】修復單列匯入的Bug,單元測驗“OneColumnImporter_Test”。問題見(https://github.com/dotnetcore/Magicodes.IE/is ......

    uj5u.com 2020-09-09 22:08:05 more
  • 在webform中使用ajax

    如果你用過Asp.net webform, 說明你也算是.NET 開發的老兵了。WEBform應該是2011 2013左右,當時還用visual studio 2005、 visual studio 2008。后來基本都用的是MVC。 如果是新開發的專案,估計沒人會用webform技術。但是有些舊版 ......

    uj5u.com 2020-09-09 22:08:50 more
  • iis添加asp.net網站,訪問提示:由于擴展配置問題而無法提供您請求的

    今天在iis服務器配置asp.net網站,遇到一個問題,記錄一下: 問題:由于擴展配置問題而無法提供您請求的頁面。如果該頁面是腳本,請添加處理程式。如果應下載檔案,請添加 MIME 映射。 WindowServer2012服務器,添加角色安裝完.netframework和iis之后,運行aspx頁面 ......

    uj5u.com 2020-09-09 22:10:00 more
  • WebAPI-處理架構

    帶著問題去思考,大家好! 問題1:HTTP請求和回傳相應的HTTP回應資訊之間發生了什么? 1:首先是最底層,托管層,位于WebAPI和底層HTTP堆疊之間 2:其次是 訊息處理程式管道層,這里比如日志和快取。OWIN的參考是將訊息處理程式管道的一些功能下移到堆疊下端的OWIN中間件了。 3:控制器處理 ......

    uj5u.com 2020-09-09 22:11:13 more
  • 微信門戶開發框架-使用指導說明書

    微信門戶應用管理系統,采用基于 MVC + Bootstrap + Ajax + Enterprise Library的技術路線,界面層采用Boostrap + Metronic組合的前端框架,資料訪問層支持Oracle、SQLServer、MySQL、PostgreSQL等資料庫。框架以MVC5,... ......

    uj5u.com 2020-09-09 22:15:18 more
  • WebAPI-HTTP編程模型

    帶著問題去思考,大家好!它是什么?它包含什么?它能干什么? 訊息 HTTP編程模型的核心就是訊息抽象,表示為:HttPRequestMessage,HttpResponseMessage.用于客戶端和服務端之間交換請求和回應訊息。 HttpMethod類包含了一組靜態屬性: private stat ......

    uj5u.com 2020-09-09 22:15:23 more
  • 部署WebApi隨筆

    一、跨域 NuGet參考Microsoft.AspNet.WebApi.Cors WebApiConfig.cs中配置: // Web API 配置和服務 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 二、清除默認回傳XML格式 ......

    uj5u.com 2020-09-09 22:15:48 more
最新发布
  • C#多執行緒學習(二) 如何操縱一個執行緒

    <a href="https://www.cnblogs.com/x-zhi/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2943582/20220801082530.png" alt="" /></...

    uj5u.com 2023-04-19 09:17:20 more
  • C#多執行緒學習(二) 如何操縱一個執行緒

    C#多執行緒學習(二) 如何操縱一個執行緒 執行緒學習第一篇:C#多執行緒學習(一) 多執行緒的相關概念 下面我們就動手來創建一個執行緒,使用Thread類創建執行緒時,只需提供執行緒入口即可。(執行緒入口使程式知道該讓這個執行緒干什么事) 在C#中,執行緒入口是通過ThreadStart代理(delegate)來提供的 ......

    uj5u.com 2023-04-19 09:16:49 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    <a href="https://www.cnblogs.com/huangxincheng/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/214741/20200614104537.png" alt="" /&g...

    uj5u.com 2023-04-18 08:39:04 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    一:背景 1. 講故事 前段時間協助訓練營里的一位朋友分析了一個程式卡死的問題,回過頭來看這個案例比較經典,這篇稍微整理一下供后來者少踩坑吧。 二:WinDbg 分析 1. 為什么會卡死 因為是表單程式,理所當然就是看主執行緒此時正在做什么? 可以用 ~0s ; k 看一下便知。 0:000> k # ......

    uj5u.com 2023-04-18 08:33:10 more
  • SignalR, No Connection with that ID,IIS

    <a href="https://www.cnblogs.com/smartstar/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/u36196.jpg" alt="" /></a>...

    uj5u.com 2023-03-30 17:21:52 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:15:33 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:13:31 more
  • C#遍歷指定檔案夾中所有檔案的3種方法

    <a href="https://www.cnblogs.com/xbhp/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/957602/20230310105611.png" alt="" /></a&...

    uj5u.com 2023-03-27 14:46:55 more
  • C#/VB.NET:如何將PDF轉為PDF/A

    <a href="https://www.cnblogs.com/Carina-baby/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2859233/20220427162558.png" alt="" />...

    uj5u.com 2023-03-27 14:46:35 more
  • 武裝你的WEBAPI-OData聚合查詢

    <a href="https://www.cnblogs.com/podolski/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/616093/20140323000327.png" alt="" /><...

    uj5u.com 2023-03-27 14:46:16 more