UWP程序用多頁面實現應用實例多開

????????Windows 10 IoT ARM64平臺下,UWP應用和MFC程序不一樣,同時只能打開一個應用實例。以串口程序為例,如果用戶希望同時打開多個應用實例,一個應用實例打開串口1,一個應用實例打開串口2,那么我們可以加載多個頁面,在各個頁面分別加載功能模塊,實現程序功能模塊多開。

????????本文以UWP串口例程為例,介紹如何用代碼實現同時打開多個串口模塊頁面,進行測試。

1.? 創建UWP工程

????????1. 打開visual studio 2022,點擊“創建新項目”。

????????2. 選擇篩選條件,語言C++,平臺選擇Windows,應用類型選擇UWP。

????????3. 選擇“空白應用”,本文以C++/CX為例。

2.? 導入需要多開的功能模塊頁面

????????1. 創建工程后,右鍵點擊工程->添加->新建項。

????????

????????2.選擇XAML空白頁,給頁面命名為SerialPage.xaml,點擊添加。

????????3. 在工程中可以看到添加的頁面SerialPage,將之前寫好的UWP串口程序代碼COPY過來(參考文章《UWP串口程序開發》),把串口程序的xaml內容拷貝到SerialPage.xaml中,把代碼文件.xaml.h和.xaml.cpp的內容也拷貝到對應文件SerialPage.xaml.h和SerialPage.xaml.cpp中。如果原UWP程序頁面名稱(默認為MainPage)和當前工程名稱(SerialPage)不一樣,注意全部替換一下。

????????4. 雙擊頁面SerialPage.xaml,檢查下是否添加成功。編譯一下,確認代碼都正確COPY過來了。

3.? 通過Navigate加載新頁面

????????UWP中頁面Frame的概念,類似MFC中的窗口Dialog,但功能更強大些。主頁面可以打開新的子頁面,頁面本身也可以執行跳轉,回退操作。頁面的回收由系統負責,當沒有Content指向頁面后,頁面自動被回收

????????在主頁面中添加一個按鈕,按鈕中執行代碼。

Windows::UI::Xaml::Controls::Frame^ frame= new ref new Windows::UI::Xaml::Controls::Frame();
frame->Navigate(TypeName(SerialPage::typeid));

????????設置新頁面為當前操作頁面。

Window.Current.Content = frame;
Window.Current.Activate();

????????每點擊一次按鈕,就可以加載一個新的SerialPage頁面了。

4.? 用導航控件SplitView管理多窗口

????????為了便于管理打開的新頁面,能在它們之間隨意切換,可以使用SplitView控件來實現。SplitView由一個導航區域和一個頁面區域組成,可以在導航區域Panel中添加不同按鈕,在點擊后,在頁面區域Content中顯示對應的頁面。根據需求,可以設置導航區域大小,是否自動隱藏等。

????????1. 在主頁面中添加一個SplitView控件,命名為SplitViewMain。在它的Pane中可以用一個StackPanel來裝按鈕,給Content命名為FrameMain,在里面隨意加一段文字。

<SplitView x:Name="SplitViewMain" DisplayMode="Inline" IsPaneOpen="True" ><SplitView.Pane><StackPanel x:Name="BtnContainer"></StackPanel></SplitView.Pane><SplitView.Content><Frame x:Name="FrameMain"><TextBlock Text="未添加測試接口" VerticalAlignment="Center" HorizontalAlignment="Center"/></Frame></SplitView.Content>
</SplitView>

????????2. 在Pane中添加幾個按鈕,可以加到StackPanel中,讓StackPanel來自動排列。

<SplitView.Pane><StackPanel x:Name="BtnContainer"><Button Content="Button1" Click="Button1_Click"/><Button Content="Button2" Click="Button2_Click"/></StackPanel>
</SplitView.Pane>

????????3. 在按鈕中加入代碼

void SPT::MainPage:: Button1_Click (Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{if (m_frame[0] == nullptr){m_frame[0] = ref new Windows::UI::Xaml::Controls::Frame();m_frame[0]->Navigate(TypeName(SerialPage::typeid));????????? //指定SerialPage}FrameMain = m_frame[0];SplitViewMain->Content = FrameMain;
}

????????這樣,就可以通過點擊不同按鈕,進入對應的頁面了

5.? 動態管理導航控件SplitView內導航按鈕

????????有時候,如果導航按鈕的數量不確定,希望根據實際情況添加或刪除導航按鈕。本文例程中,每點擊一次添加按鈕,便添加一個串口測試頁面,做法如下。

????????1. 在主頁面中添加一個按鈕,點擊一次,便在SplitView的Pane里加入一個按鈕,給這個按鈕設置參數Tag,便于區分不同按鈕。給按鈕綁定點擊響應函數OnClick。

void SPT::MainPage::BtnSerial_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{Button^ newButton;newButton = ref new Button;
m_Count++;newButton->Tag = m_Count;newButton->Click += ref new Windows::UI::Xaml::RoutedEventHandler(this, &SPT::MainPage::OnClick);BtnContainer->Children->Append(newButton);m_frame[m_Count] = ref new Windows::UI::Xaml::Controls::Frame();m_frame[m_Count]->Navigate(TypeName(SerialPage::typeid));FrameMain = m_frame[m_Count];SplitViewMain->Content = FrameMain;
}

????????2. 在按鈕的響應函數中讀出按鈕參數,根據不同的參數決定如何處理,加載哪個頁面。

void SPT::MainPage::OnClick(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{Button^ clickButton = safe_cast<Button^>(sender);int id = safe_cast<int>(clickButton->Tag);if (m_frame[id] == nullptr){return; }FrameMain = m_frame[id];SplitViewMain->Content = FrameMain;
}

6.? 主頁面與導航打開的新頁面之間數據通信

????????目前導航頁面和加載的子頁面相對獨立,很多時候主界面需要傳遞數據給子頁面,便于子頁面初始化,甚至需要給子頁面提供函數接口。子頁面退出時也需要回調函數通知主頁面,并返回處理后的數據。

????????本文串口例程中

? ? ? ? 1. 設置一個數據結構,把所有主頁面要傳輸的數據打包到這個數據接口中。文本例程中打包數據包括子頁面ID,和一個回調接口。

public ref class PageData sealed : public Platform::Object
{
public:PageData(int initValue, Windows::Foundation::EventHandler<int>^ callback): _initValue(initValue), _exitCallback(callback){}property int InitValue {int get() { return _initValue; }}property Windows::Foundation::EventHandler<int>^ ExitCallback {Windows::Foundation::EventHandler<int>^ get() { return _exitCallback; }}
private:int _initValue;Windows::Foundation::EventHandler<int>^ _exitCallback;
};

? ? ? ? 2. 在主頁面加載子頁面時,將打包數據一起傳過去,修改Navigate調用。

m_frame[i] = ref new Windows::UI::Xaml::Controls::Frame();
auto exitHandler = ref new Windows::Foundation::EventHandler<int>(this, &MainPage::OnPageExit);
auto data = ref new PageData(i, exitHandler);
m_frame[i]->Navigate(TypeName(SerialPage::typeid), data);
FrameMain = m_frame[i];
SplitViewMain->Content = FrameMain;

????????3. 子頁面SerialPage重載OnNavigatedTo函數,添加初始化代碼

virtual void OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override;
Windows::Foundation::EventHandler<int>^ m_ExitCallback;void SerialPage::OnNavigatedTo(NavigationEventArgs^ e)
{auto data = dynamic_cast<PageData^>(e->Parameter);if (data != nullptr){m_id = data->InitValue;m_ExitCallback = data->ExitCallback;}
}

????????4. 子頁面退出時調用回調函數,傳回參數頁面ID

void SPT::SerialPage::BtnExit_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{try{CancelReadTask();ClosePort();}catch (Platform::Exception^ ex){}if (Frame->CanGoBack){Frame->GoBack();}Frame->Content = nullptr;if (m_ExitCallback != nullptr){m_ExitCallback->Invoke(this, m_id);}
}

????????5. 主頁面處理回調函數

void SPT::MainPage::OnPageExit(Platform::Object^ sender, int id)
{for (int i = 0; i < BtnContainer->Children->Size; ++i){if (Button^ btn = dynamic_cast<Button^>(BtnContainer->Children->GetAt(i))){if (btn->Tag != nullptr && safe_cast<int>(btn->Tag) == id){BtnContainer->Children->RemoveAt(i);return;}}}
}

7.? 界面優化

????????調整控件的邊界Margin,用LinearGradientBrush設置頁面及控件背景色,在代碼中適當調整控件字體樣式,使得界面滿足設計需求。

8.? 調試

????????打開Win10 IoT板子上的調試助手。

????????選擇工程平臺為ARM64,編譯運行,示例如下。

????????需要程序源碼可以聯系英創工程師獲得。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/75608.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/75608.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/75608.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Springboot整合Netty簡單實現1對1聊天(vx小程序服務端)

本文功能實現較為簡陋&#xff0c;demo內容僅供參考&#xff0c;有不足之處還請指正。 背景 一個小項目&#xff0c;用于微信小程序的服務端&#xff0c;需要實現小程序端可以和他人1對1聊天 實現功能 Websocket、心跳檢測、消息持久化、離線消息存儲 Netty配置類 /*** au…

GitLab 中文版17.10正式發布,27項重點功能解讀【二】

GitLab 是一個全球知名的一體化 DevOps 平臺&#xff0c;很多人都通過私有化部署 GitLab 來進行源代碼托管。極狐GitLab 是 GitLab 在中國的發行版&#xff0c;專門為中國程序員服務。可以一鍵式部署極狐GitLab。 學習極狐GitLab 的相關資料&#xff1a; 極狐GitLab 官網極狐…

好消息!軟航文檔控件(NTKO WebOffice)在Chrome 133版本上提示擴展已停用的解決方案

軟航文檔控件現有版本依賴Manifest V2擴展技術支持才能正常運行&#xff0c;然而這個擴展技術到2025年6月在Chrome高版本上就徹底不支持了&#xff0c;現在Chrome 133開始的版本已經開始彈出警告&#xff0c;必須手工開啟擴展支持才能正常運行。那么如何解決這個技術難題呢&…

字典樹與01trie

字典樹簡介 當我們通過字典查一個字或單詞的時候&#xff0c;我們會通過前綴或關鍵字的來快速定位一個字的位置&#xff0c;進行快速查找。 字典樹就是類似字典中索引表的一種數據結構&#xff0c;能夠幫助我們快速定位一個字符串的位置。 字典樹是一種存儲字符串的數據結構…

二十五、實戰開發 uni-app x 項目(仿京東)- 前后端輪播圖

定義了一個名為 Swiper 的Java類,用于表示一個輪播圖實體。它使用了 Jakarta Persistence API (JPA) 來映射數據庫表,并使用了 Lombok 庫來簡化代碼。以下是對代碼的詳細講解: 1. 包聲明 package com.jd.jdmall.model; 這行代碼聲明了該類所在的包路徑為 com.jd.jdmall.mode…

游戲搖桿開發:利用 Windows API 實現搖桿輸入捕獲

在現代游戲開發中&#xff0c;游戲搖桿&#xff08;Joystick&#xff09;作為一種重要的輸入設備&#xff0c;能夠為玩家提供更加沉浸式的游戲體驗。Windows 操作系統提供了一系列 API 函數&#xff0c;允許開發者輕松地捕獲和處理游戲搖桿的輸入。本文將介紹如何使用 Windows …

Ceph集群2025(Squid版)快速對接K8S cephFS文件存儲

ceph的塊存儲太簡單了。所以不做演示 查看集群 創建一個 CephFS 文件系統 # ceph fs volume create cephfs01 需要創建一個子卷# ceph fs subvolume create cephfs01 my-subvol -----------------#以下全部自動創建好 # ceph fs ls name: cephfs01, metadata pool: c…

Python中數據結構元組詳解

在Python中&#xff0c;元組&#xff08;Tuple&#xff09;是一種不可變的序列類型&#xff0c;常用于存儲一組有序的數據。與列表&#xff08;List&#xff09;不同&#xff0c;元組一旦創建&#xff0c;其內容無法修改。本文將詳細介紹元組的基本操作、常見運算、內置函數以及…

游戲引擎學習第183天

回顧和今天的計劃 我對接下來的進展感到非常興奮。雖然我們可能會遇到一些問題&#xff0c;但昨天我們差不多完成了將所有內容遷移到新的日志系統的工作&#xff0c;我們正在把一些內容整合進來&#xff0c;甚至是之前通過不同方式記錄時間戳的舊平臺層部分&#xff0c;現在也…

Spring 如何處理循環依賴

在 Spring 框架里&#xff0c;循環依賴指的是多個 Bean 之間相互依賴&#xff0c;從而形成一個閉環。例如&#xff0c;Bean A 依賴 Bean B&#xff0c;而 Bean B 又依賴 Bean A。Spring 主要通過三級緩存機制來處理循環依賴&#xff0c;下面詳細介紹相關內容。 1. 三級緩存的定…

Android開發layer-list

Android開發layer-list 它的用處可以在drawable上進行多圖拼接&#xff0c;比如啟動頁&#xff0c;不想圖片被拉伸就這么做。還有做某些線突出來。 示例代碼&#xff1a; <?xml version"1.0" encoding"utf-8"?> <layer-list xmlns:android&q…

手機測試,工作中學習

要學習各種機型的截圖方式、開發模式在哪。 榮耀機型&#xff1a;截圖&#xff1a;關節快速敲兩下。開發者模式在“系統和更新”里。 1.出現缺陷&#xff0c;需要獲取日志。 學習adb生成日志&#xff1a;當測試中出現缺陷的&#xff0c;使用adb logcat -d > d:/log.txt …

OBS虛擬背景深度解析:無需綠幕也能打造專業教學視頻(附插件對比)

想要錄制教學視頻卻苦于背景雜亂&#xff1f;本文將手把手教你用OBS實現專業級虛擬背景效果&#xff0c;無需綠幕也能輕松營造沉浸式教學場景。文末附6個提升畫面質感的免費背景資源&#xff01; 一、虛擬背景的核心價值&#xff1a;從「教師宿舍」到「虛擬講堂」的蛻變 我們調…

零基礎搭建智能法律知識庫!騰訊云HAI實戰教程

為什么需要法律知識庫&#xff1f; 想象一下&#xff0c;你的所有法律文件都在手邊&#xff0c;隨時可以搜索和分析。這就是法律知識庫的魅力所在。對于法律專業人士、處理大量法律文檔的企業&#xff0c;甚至是希望了解法律事項的普通人來說&#xff0c;法律知識庫都是一個不…

Rust從入門到精通之進階篇:19.Rust 生態系統

Rust 生態系統 Rust 擁有一個豐富而活躍的生態系統&#xff0c;提供了各種庫和框架來支持不同領域的開發。在本章中&#xff0c;我們將探索 Rust 生態系統中的主要組件&#xff0c;了解常用的庫和工具&#xff0c;以及如何在項目中有效地使用它們。 Rust 包管理&#xff1a;C…

前端面試:如何去衡量用戶操作過程中否卡頓?

衡量用戶在應用中的操作是否卡頓是前端開發中的一個關鍵任務&#xff0c;涉及用戶體驗的各個方面。以下是一些常用的方法和工具&#xff0c;可以幫助你有效地評估用戶操作中的卡頓情況&#xff1a; 1. 使用性能分析工具 瀏覽器開發者工具&#xff1a;大多數現代瀏覽器&#xf…

Python技術棧與數據可視化創意實踐詳解(三)

Python在數據可視化領域憑借豐富的庫和靈活的生態系統&#xff0c;能夠實現從基礎圖表到復雜交互式可視化的全場景覆蓋。以下從技術選型、創意實現到實戰優化進行系統化解析&#xff0c;并提供可直接落地的代碼示例。 一、Python數據可視化技術棧 1. 基礎與統計可視化 Matplotl…

訂票系統|基于Java+vue的火車票訂票系統(源碼+數據庫+文檔)

訂票系統目錄 基于Springbootvue的火車票訂票系統 一、前言 二、系統設計 三、系統功能設計 1會員信息管理 2 車次信息管理 3訂票訂單管理 4留言板管理 四、數據庫設計 五、核心代碼 六、論文參考 七、最新計算機畢設選題推薦 八、源碼獲取&#xff1a; 博主介紹…

Snowflake 算法的實現

snowflake(雪花算法)是一個開源的分布式 ID 生成算法&#xff0c;結果是一個 long 型的 ID。snowflake 算法將 64bit 劃分為多段&#xff0c;分開來標識機器、時間等信息&#xff0c;具體組成結構如下圖所示&#xff1a; snowflake 算法的核心思想是使用 41bit 作為毫秒數&…

C 語言中, scanf 函數在哪些情況下會結束輸入讀取:

在 C 語言中&#xff0c; scanf 函數在以下幾種情況下會結束輸入讀取&#xff1a; &#xff1a; 1. 遇到指定格式匹配失敗&#xff1a; scanf 按照格式字符串要求讀取輸入。當輸入數據格式與格式字符串不匹配時&#xff0c;就會結束讀取。例如 scanf(“%d”, &num) 要求輸…