WinUI3入門9:自制SplitPanel

初級代碼游戲的專欄介紹與文章目錄-CSDN博客

我的github:codetoys,所有代碼都將會位于ctfc庫中。已經放入庫中我會指出在庫中的位置。

這些代碼大部分以Linux為目標但部分代碼是純C++的,可以在任何平臺上使用。

源碼指引:github源碼指引_初級代碼游戲的博客-CSDN博客

C#是我多年以來的業余愛好,新搞的東西能用C#的就用C#了。


? ? ? ? WinUI3里面有個SplitView,實現了兩塊面板,但是是不帶鼠標拖動改變大小的功能的,其設計目標不是兩塊面板,而是根據需要隱藏一個面板。

????????一般來說,移動設備上確實不需要用戶改變界面比例,但是你是WinUI3啊。所以說微軟腦子里都是些什么啊,不如大家都散了算了。

? ? ? ? 因為寫Winforms程序的時候我非常依賴手動調整界面比例,對于不能自主調整的完全不能忍,所以,我必須實現一個SplitPanel。

目錄

一、設計SplitPanel的基本原理

二、編寫xaml

三、處理鼠標事件

3.1 初始化

3.2 鼠標事件

四、效果


一、設計SplitPanel的基本原理

? ? ? ? 通過鼠標改變界面大小的功能總是涉及到這些技術:

  • 動態設置控件/窗口的位置和尺寸,當然這沒什么難度
  • 處理鼠標事件,根據鼠標位置計算鼠標移動的距離,從而改變界面比例
  • 捕獲鼠標,為什么需要捕獲鼠標?因為鼠標移出控件/窗口之后就無法獲得鼠標事件,這樣能實現縮小但是無法實現變大。而捕獲鼠標就是告訴操作系統即使鼠標移出也仍然要發送鼠標事件

? ? ? ? 結合以上幾點,一般實現鼠標改變界面大小的實現方法是:

  • 在鼠標按下時記錄鼠標位置,捕獲鼠標
  • 在鼠標移動時根據鼠標移動距離改變界面大小
  • 在鼠標釋放時停止捕獲鼠標

? ? ? ? 在WinUI3里面我們可以借助Grid來實現:

左面板分隔條右面板

? ? ? ? 分隔條用Border就可以了,寬度2-3像素,1個像素很難點擊,7、8個像素又太粗壯不好看。

? ? ? ? 左面板、右面板任意。

二、編寫xaml

		<Grid><Grid.ColumnDefinitions><ColumnDefinition Width="3*" x:Name="col_mainlist" /><ColumnDefinition Width="3" /><ColumnDefinition Width="1*"  x:Name="col_preview" /></Grid.ColumnDefinitions><!-- 主列表 --><controls:DataGrid Grid.Column="0" x:Name="MainDataList" BorderBrush="Black" BorderThickness="1" Margin="2" Padding="2"Height="Auto" Background="LightGray"GridLinesVisibility="All" HorizontalGridLinesBrush="Blue" VerticalGridLinesBrush="Green" AutoGenerateColumns="True" /><!-- 分隔條 --><Border Grid.Column="1" x:Name="border_split" BorderBrush="Gray" BorderThickness="3" Margin="0,2,0,2" /><!-- 預覽區 --><Grid Grid.Column="2" BorderBrush="Black" BorderThickness="1" Margin="2" Padding="2">。。。。。。</Grid></Grid>

? ? ? ? ?這個Grid只有一行,所以沒有定義行。有三個列,分別對應左面板、分隔條、右面板。分隔條固定為3個像素,左面板和右面板為3:1分配。左面板是DataGrid,右面板是個子Grid。

? ? ? ? 左右面板都有x:Name,因為我們需要同時改變左右面板的大小。你說改變DataGrid和子Grid的大小,讓總Grid自適應行不行?這種自適應的東西很詭異,我是不太放心的。

? ? ? ? 用作分隔條的Border上也有x:Name,我們設置鼠標事件都在它上面。

? ? ? ? 這段xaml中的主列表和預覽區是我實際的內容,和要實現的SplitPanel功能沒有任何關系。

三、處理鼠標事件

3.1 初始化

			//設置拖動手柄border_split.PointerPressed += OnPointerPressed;border_split.PointerReleased += OnPointerReleased;

? ? ? ? 在窗口的構造函數里增加上述代碼。為什么沒有設置PointerMoved事件?因為沒有按下鼠標的時候處理PointerMoved是沒有意義的。

3.2 鼠標事件

		private void OnPointerMoved(object sender, Microsoft.UI.Xaml.Input.PointerRoutedEventArgs e){FrameworkElement? control = sender as FrameworkElement;if (null == control) return;try{foreach (var pointer in control.PointerCaptures){//control.PointerCaptures.Contains(e.Pointer)是無效的,必須用PointerId來比較if (pointer.PointerId== e.Pointer.PointerId){ChangeControlSize(control, e);}}}catch (Exception ex){_ = ShowMessageBox(ex.Message, "Exception");}}private void OnPointerReleased(object sender, Microsoft.UI.Xaml.Input.PointerRoutedEventArgs e){FrameworkElement? control = sender as FrameworkElement;if (null == control) return;try{foreach (var pointer in control.PointerCaptures){//control.PointerCaptures.Contains(e.Pointer)是無效的,必須用PointerId來比較if (pointer.PointerId == e.Pointer.PointerId){control.PointerMoved -= OnPointerMoved; ;this.Title = "PointerReleased";control.ReleasePointerCapture(e.Pointer);}}}catch (Exception ex){_ = ShowMessageBox(ex.Message, "Exception");}}private void OnPointerPressed(object sender, Microsoft.UI.Xaml.Input.PointerRoutedEventArgs e){FrameworkElement? control = sender as FrameworkElement;if (null == control) return;if (!control.CapturePointer(e.Pointer)){this.Title = "CapturePointer error";return;}control.PointerMoved += OnPointerMoved; ;pos = e.GetCurrentPoint(control).Position.X;this.Title = "PointerPressed " + pos.ToString() + " - " + control.ActualWidth.ToString()+ " control.PointerCaptures "+ control.PointerCaptures.Count.ToString();}double pos = 0;private void ChangeControlSize(FrameworkElement? control, Microsoft.UI.Xaml.Input.PointerRoutedEventArgs e){if (null == control) return;double move = e.GetCurrentPoint(control).Position.X - pos;if (move >= 0){if (col_preview.ActualWidth - move < 0) return;}else{if (col_mainlist.ActualWidth + move < 0) return;}col_preview.Width = new GridLength(col_preview.ActualWidth - move);col_mainlist.Width = new GridLength(col_mainlist.ActualWidth + move);}

? ? ? ? 這段代碼還是比較嚴謹的,左右面板的名字可以隨意替換。唯一不太嚴謹的是記錄鼠標初始位置的pos,一般不建議全局變量用這樣簡單的方式命名。

? ? ? ? 這個代碼里面有一部分沒有完善處理:假設了只有一個鼠標,但仍然判斷了是否正在進行鼠標捕獲(根據這個假設和鼠標按下才處理鼠標移動,并不需要檢查是否是正在捕獲的鼠標)。嚴謹的方式是根據鼠標ID來分別處理,設想,如果有兩個鼠標同時操作會怎么樣?

? ? ? ? 處理是否是正在捕獲的鼠標的時候遇到了一個坑,我已經在代碼里指出。并不能簡單地用鼠標對象是否在集合中來判斷,必須一個一個比較ID。

? ? ? ? 這段代碼只處理了寬度,如果要做縱向的,稍微修改就可以了。

四、效果

? ? ? ? 差不多就是這個意思了。當然,最好能把鼠標改成專門的鼠標形狀。

?


(這里是文檔結束)

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

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

相關文章

【面板數據】上市公司投資者保護指數(2010-2023年)

上市公司投資者保護指數是基于上市公司年報中公開披露的多項內容&#xff0c;從信息透明度、公司治理結構、關聯交易披露、控股股東行為規范等多個維度&#xff0c;評估企業是否在制度上和實際操作中有效保障投資者&#xff0c;特別是中小投資者的合法權益。本分享數據基于我國…

如何解決USB遠距離傳輸難題?一文了解POE USB延長器及其行業應用

在日常辦公、教學、醫療和工業系統中&#xff0c;USB接口設備扮演著越來越關鍵的角色。無論是視頻采集設備、鍵盤鼠標&#xff0c;還是打印機、條碼槍&#xff0c;USB早已成為主流連接標準。然而&#xff0c;USB原生傳輸距離的限制&#xff08;通常在5米以內&#xff09;常常成…

PostgreSQL(TODO)

(TODO) 功能MySQLPostgreSQLJSON 支持支持&#xff0c;但功能相對弱非常強大&#xff0c;支持 JSONB、索引、函數等并發控制行級鎖&#xff08;InnoDB&#xff09;&#xff0c;不支持 MVCC多版本并發控制&#xff08;MVCC&#xff09;&#xff0c;性能更好存儲過程/觸發器支持&…

LINUX 623 FTP回顧

FTP 權限 /etc/vsftpd/vsftpd.conf anonymous_enableNO local_enableNO 服務器 .20 [rootweb vsftpd]# grep -v ^# vsftpd.conf anonymous_enableNO local_enableYES local_root/data/kefu2 chroot_local_userYES allow_writeable_chrootYES write_enableYES local_umask02…

leetcode:77. 組合

學習要點 學習回溯思想&#xff0c;學習回溯技巧&#xff1b;大家應當先看一下下面這幾道題 leetcode&#xff1a;46. 全排列-CSDN博客leetcode&#xff1a;78. 子集-CSDN博客leetcode&#xff1a;90. 子集 II-CSDN博客 題目鏈接 77. 組合 - 力扣&#xff08;LeetCode&#x…

自定義主題,echarts系列嵌套

自定義主題&#xff0c;echarts系列嵌套&#xff0c;完善map地圖系列與lines系列拋物線 自定義主題開發設計&#xff08;如傳感器數據可視化&#xff09; 1.使用typetreemap自定義 TreeMap 主題&#xff08;矩形樹圖系列&#xff09; 2.在矩形樹圖中畫typelines動態連線和typee…

速度與精度的結合:Faster R-CNN模型的性能剖析

目標檢測作為計算機視覺領域的核心問題之一&#xff0c;其重要性隨著深度學習技術的發展而日益凸顯。本文深入探討了基于深度學習的Faster R-CNN模型&#xff0c;這是一種革命性的目標檢測框架&#xff0c;它通過引入區域提議網絡&#xff08;Region Proposal Network, RPN&…

計算機網絡--期末速通版

以下總結提綱來自于hcgg&#xff0c;偉大無需多言。socket編程沒有寫進去&#xff0c;Rdt的話我后來感覺可能只考概念&#xff0c;其余我感覺會考的部分都在里面了&#xff0c;如果有錯誤或者解釋不清楚造成的疑問&#xff0c;希望大家及時指正&#xff0c;感謝。 應用層 DNS…

AI浪潮拐點:MCP與A2A協議如何重塑AI智能體協作生態

一、AI技術演進的必然拐點:從單機智能到群體協作 當AI技術從單模型推理邁向復雜系統協作,MCP(模型協作協議)與A2A(智能體間協作協議)的誕生標志著產業變革的關鍵轉折點。這一演進并非偶然,而是技術發展與社會需求雙重驅動的必然結果。 從技術脈絡看,AI正經歷從"…

Python pyecharts基礎(一)

pyecharts 安裝 pip安裝 pip(3) install pyecharts源碼安裝 $ git clone https://github.com/pyecharts/pyecharts.git $ cd pyecharts $ pip install -r requirements.txt $ python setup.py install # 或者執行 python install.py查看版本 import pyecharts print(pyecha…

【論文閱讀】人工智能在直升機航空電子系統中的應用

人工智能在直升機航空電子系統中的應用 論文摘要文章結構參考文獻 論文摘要 論文摘要:在現代戰爭形勢日趨信息化、智能化的背景下&#xff0c;將人工智能應用于武器裝備已經是大勢所趨。針對直升機飛行任務的特征&#xff0c;對其發展狀況進行了描述&#xff0c;并對其作業能力…

矩陣階數(線性代數) vs. 張量維度(深度學習):線性代數與深度學習的基石辨析,再也不會被矩陣階數給混淆了

文章目錄 前言第一部分&#xff1a;重溫矩陣階數 - 方陣的專屬標簽第二部分&#xff1a;深入張量維度 - 深度學習的多維容器第三部分&#xff1a;核心區別總結第四部分&#xff1a;在深度學習中為何混淆&#xff1f;如何區分&#xff1f;結論 前言 在線性代數的殿堂里&#xf…

滲透測試指南(CSMSF):Windows 與 Linux 系統中的日志與文件痕跡清理

目錄 &#x1f575;??♂? 一、清理日志的重要性 核心目標 案例&#xff1a;域控滲透后日志暴露 &#x1f5a5;? 二、Windows系統日志清理 1. 事件日志&#xff08;Event Logs&#xff09; 2. Web日志&#xff08;IIS Logs&#xff09; 3. PowerShell日志 4. 其他日…

MYSQL數據庫和MSSQL數據庫有什么區別?如何進行備份和還原?

MySQL 和 MSSQL 是兩種廣泛使用的關系型數據庫&#xff0c;但它們在架構、功能、性能、平臺支持以及使用場景等方面存在許多差異。以下是詳細的區別&#xff0c;以及兩者的備份和還原方法。 1. MySQL 與 MSSQL 的區別 1.1 基本概念 數據庫MySQLMSSQL開發者Oracle&#xff08;…

vscode搭建spring boot項目

一.創建項目 第一步&#xff1a;打開vscode按下shiftctrlp,選擇下面的 第二步&#xff1a;選擇版本 第三步&#xff1a;選擇語言 第四步&#xff1a;填寫項目的Groupid 第五步&#xff1a;填寫Artifact id 第六步&#xff1a;選擇打包方式 第七步&#xff1a;選擇java版本 第…

Matter協議開發者指南:使用Matter SDK構建智能家居應用

更新請關注&#xff1a;Matter協議開發者指南&#xff1a;使用Matter SDK構建智能家居應用 智能家居的演變從根本上改變了我們日常生活中與技術互動的方式。從語音助手到自動化照明和安防系統&#xff0c;機遇似乎無窮無盡。然而&#xff0c;開在這個迅速擴張的領域中&#xff…

中科院1區TOP|IF8.3:廣西中醫藥大學團隊采用代謝組學-網絡藥理學整合策略,闡明雞骨草的多靶點作用機制

中科院1區TOP|IF8.3&#xff1a;廣西中醫藥大學團隊采用代謝組學-網絡藥理學整合策略&#xff0c;闡明雞骨草的多靶點作用機制 在當今生命科學研究領域&#xff0c;代謝性疾病的防治與傳統中藥的現代化研究已成為兩大備受矚目的熱點方向。隨著全球范圍內脂質代謝紊亂相關疾病發…

c++中 Lambda表達式

Lambda優化技巧 盡量使用值捕獲簡單類型 避免捕獲大型對象(使用引用或智能指針) 將不修改的捕獲標記為const 使用初始化捕獲移動語義資源 前言 1. Lambda表達式基本語法 [捕獲列表](參數列表) mutable(可選) 異常屬性(可選) -> 返回類型(可選) {// 函數體 } 捕獲列表…

睿是信息攜手Arctera,深化服務中國市場,共筑數據管理新未來

2025年6月23日&#xff0c;為了更加深入服務中國大陸地區的廣大用戶&#xff0c;上海睿是信息科技有限公司&#xff08;以下簡稱“睿是信息”&#xff09;與全球數據管理領域的領導者Arctera&#xff0c;雙方正式達成戰略合作&#xff0c;自2025年7月7日起&#xff0c;睿是信息…

【WebGIS系列】WebGIS 開發相關的資源

目錄 數據 GIS 軟件 地圖渲染庫 EPSG 相關工具 資源 以下為個人收集的與 WebGIS 開發相關的資源&#xff08;排名不分前后&#xff09;&#xff0c;歡迎補充。 數據 天地圖(opens in a new tab)國家統計局行政區劃(opens in a new tab)民政部全國行政區劃信息查詢平臺(…