WPF怎么做新手引導界面?

本文經原作者授權以原創方式二次分享,歡迎轉載、分享。

原文作者:眾尋

原文鏈接:https://www.cnblogs.com/ZXdeveloper/p/8391864.html


這兩天不忙,所以,做了一個簡易的新手引導小Demo。因為,不是項目上應用,所以,做的很粗糙,也就是給需要的人,一個思路而已。

新手引導功能的話,就是告訴用戶,頁面上操作的順序,第一步要做什么,第二步要做什么,以此類推,然后,最終關閉新手引導頁面。

以我的習慣,還是先給大家看看效果。

a4af3e813b3fbb9f9c4ed752e629ebef.gif

效果展示的很簡單,就是將要告訴用戶操作的控件做一個提示。

要實現這個功能化,那思路就是大概以下幾項:

一、遮罩窗體

將主窗體進行遮罩,半透明的效果,常用的做遮罩的話,一般是設置一個底色,然后設置透明度,類似于這篇博客 WPF透明窗體制作[1],但是,在實際的操作用就會遇到問題,如果使用正常的半透明方式的話,黃色框部分,是不發透出白色的主窗體內容的,因為已經有底色了,所以,本文使用的半透明方法是Clip的擦除,效果如下圖,參考的博客WPF 用Clip屬性實現蒙板特效[2]

2641326af8a69b2f4737608a6c48693e.png

先設置一個透明的窗體

<Window?x:Class="SimpleGuide.GuideWin"?xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"?xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"?xmlns:d="http://schemas.microsoft.com/expression/blend/2008"?xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"?xmlns:local="clr-namespace:SimpleGuide"?mc:Ignorable="d"?Title="GuideWin"?WindowStyle="None"?AllowsTransparency="True"?x:Name="gw"?Background="#01FFFFFF"?ShowInTaskbar="False"><Grid><Border?x:Name="bor"?BorderBrush="White"?BorderThickness="2"?CornerRadius="5"?Opacity="0.8"><Border.Effect><DropShadowEffect?ShadowDepth="0"?Color="#FF414141"?BlurRadius="8"?/></Border.Effect><Border?Background="Black"?Opacity="0.5"?Margin="0"?CornerRadius="5"?/></Border><Canvas?x:Name="can"></Canvas></Grid>
</Window>

從XAML的代碼中,可以看到Background這個屬性沒用“Transparent”而用的是“#01FFFFFF”,因為如果用Transparent的話,那真的就是透明了,可以直接點擊到主窗體里的控件,這個是我們所不希望的,所以,設置了“#01FFFFFF”,一個近乎透明的顏色。

二、顯示要操作的控件

既然要對某個控件進行指引的話,那就要把控件先給圈起來,圈起來的首要任務,就是獲得控件在當前窗體的坐標位置。

Point?point?=?fe.TransformToAncestor(Window.GetWindow(fe)).Transform(new?Point(0,?0));

當獲取完坐標以后,則需要將控件給圈起來,我的方法,就是取當前的坐標-5,寬和高+10,來繪制一個空白的區域,其實,這個部分應該是指擦除

RectangleGeometry?rg1?=?new?RectangleGeometry();
rg1.Rect?=?new?Rect(point.X?-?5,?point.Y?-?5,?fe.ActualWidth?+?10,?fe.ActualHeight?+?10);
borGeometry?=?Geometry.Combine(borGeometry,?rg1,?GeometryCombineMode.Exclude,?null);

三、繪制一個指引的UC

指引UC,設計起來就比較方便了,樣子其實挺簡單的

4eeef69d507c5343386bfbae87b3373b.png

就是用Path,繪制一個范圍,但是虛線框,最開始的想法是用Line去做,但是感覺太費事了,就直接用的StrokeDashArray這個屬性,Stroke是Path本身的邊框線,當然,真的是邊框,所以,又不好設置Margin或者Padding,所以,最后的做法,就是,在外層又繪制了一個區域,只是這個區域不包含邊框線而已,填充色相同

<Path?Fill="#FF2FBEED"><Path.Data><GeometryGroup><PathGeometry?Figures="M?8,22?A?12,12?0?1?1?22,8?L?102?8?L?102?62?L?8?62?Z"?/></GeometryGroup></Path.Data>
</Path>
<Path?StrokeThickness="1"?Stroke="White"?StrokeDashArray="2,1"?Fill="#FF2FBEED"><Path.Data><GeometryGroup><PathGeometry?Figures="M?10,20?A?10,10?0?1?1?20,10?L?100?10?L?100?60?L?10?60?Z"?/></GeometryGroup></Path.Data>
</Path>

顯示內容的部分是一個Textblock,當時遇到了一個問題,就是換行問題,Textblock必須要有Width,才會換行,但是由于最外層是Viewbox,所以,嘗試過獲取UC的Width或者ActualWidth,都不行,所以,最后的解決辦法是,傳入一個窗體的寬度和高度進來,而不是在外部設置此UC的寬和高。

public?HintUC(string?xh,?string?content,?Visibility?vis?=?Visibility.Visible,?int?width?=?260,?int?height?=?160)
{InitializeComponent();this.Width?=?width;this.Height?=?height;this.tb_nr.Width?=?width?/?4;this.tb_xh.Text?=?xh;this.tb_nr.Text?=?content;this.btn_next.Visibility?=?vis;
}

四、下一步的觸發

觸發下一步,相當于是子控件調用主控件的事件,這樣的話,就是寫一個委托,在主窗體里去實現具體的方法。

private?void?show(int?xh,?FrameworkElement?fe,?string?con,?Visibility?vis?=?Visibility.Visible)
{Point?point?=?fe.TransformToAncestor(Window.GetWindow(fe)).Transform(new?Point(0,?0));//獲取控件坐標點RectangleGeometry?rg?=?new?RectangleGeometry();rg.Rect?=?new?Rect(0,?0,?this.Width,?this.Height);borGeometry?=?Geometry.Combine(borGeometry,?rg,?GeometryCombineMode.Union,?null);bor.Clip?=?borGeometry;RectangleGeometry?rg1?=?new?RectangleGeometry();rg1.Rect?=?new?Rect(point.X?-?5,?point.Y?-?5,?fe.ActualWidth?+?10,?fe.ActualHeight?+?10);borGeometry?=?Geometry.Combine(borGeometry,?rg1,?GeometryCombineMode.Exclude,?null);bor.Clip?=?borGeometry;HintUC?hit?=?new?HintUC(xh.ToString(),?con,?vis);Canvas.SetLeft(hit,?point.X?+?fe.ActualWidth?+?3);Canvas.SetTop(hit,?point.Y?+?fe.ActualHeight?+?3);hit.nextHintEvent?-=?Hit_nextHintEvent;hit.nextHintEvent?+=?Hit_nextHintEvent;can.Children.Add(hit);index++;
}
private?void?Hit_nextHintEvent()
{if?(list[index?-?1]?!=?null){can.Children.Clear();}if?(index?==?list.Count?-?1)show(index?+?1,?list[index].Uc,?list[index].Content,?Visibility.Collapsed);elseshow(index?+?1,?list[index].Uc,?list[index].Content);
}

我們要在外部聲明一個index的變量來記錄當前的List集合的索引,首先要判斷,當前的內容里,是否不為空,如果是的話,要清除掉,如果不清除的話,就會看到一堆的提示框,然后,判別是否是List集合里的最后一個控件了,如果是的話,那就不再顯示“下一步按鈕了”。

五、擴展部分

由于是一個小Demo,所以發現了一些問題,但是就沒有再解決了,例如如果主窗體不是無邊框的話,取值定位會有問題。

這是由于彈出的引導窗體獲取了主窗體的大小,但是Point去獲取控件坐標位置的時候,主窗體是不包含頭部的,由于遮罩沒有頭部,所以定位出錯了,這個我還沒有找到好的解決辦法,如果有大神知道如何解決的話,請賜教,謝謝了。

ff325472a040420a815833d129c55c31.png

顯示引導內容的部分,也可以換成一個Grid,這樣的話,就可以傳入UserControl了,有興趣的朋友可以自行修改。

源碼:Demo[3]

站長使用體驗

效果確實不錯,站長通過原作者的源碼改了一點(代碼[4]),需要遮罩的控件換成Image控件也是相同效果,nice:

139908c62c5e432efa970779b7159e03.gif

參考資料

[1]

WPF透明窗體制作: http://blog.csdn.net/cmis7645/article/details/7781990

[2]

WPF 用Clip屬性實現蒙板特效: http://blog.csdn.net/feitiankoulan/article/details/25201593

[3]

Demo: https://files.cnblogs.com/files/ZXdeveloper/SimpleGuide.zip

[4]

代碼: https://github.com/dotnet9/TerminalMACS.ManagerForWPF/tree/master/src/Demo/SimpleGuide

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

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

相關文章

最全js表單驗證

/***************************************************************** 表單校驗工具類 (linjq) *****************************************************************//** * 判斷整數num是否等于0 * * param num * return * author jiqinlin */function isIntEqZero(num){ r…

《看聊天記錄都學不會C語言?太菜了吧》(19)鞏固開始,數字1、2、3、4能夠組成多少個 3 位數的不同的排列

若是大一學子或者是真心想學習剛入門的小伙伴可以私聊我&#xff0c;若你是真心學習可以送你書籍&#xff0c;指導你學習&#xff0c;給予你目標方向的學習路線&#xff0c;無套路&#xff0c;博客為證。 本系列文章將會以通俗易懂的對話方式進行教學&#xff0c;對話中將涵蓋…

阿里云MaxCompute香港開服 將引入更多人工智能服務

9月18日&#xff0c;阿里云宣布大數據計算服務MaxCompute在香港正式開服。通過MaxCompute強大的計算能力&#xff0c;阿里云將為香港市場提供更多的人工智能產品&#xff0c;助力當地企業智能化升級。據了解&#xff0c;MaxCompute向用戶提供了完善的數據導入方案以及多種經典的…

【經典回放】多種語言系列數據結構算法:串(C版)

我們這里說的串、就是標準的C語言的串,這點,和我們教材中另行定義的串并不一致。我們這里強調僅僅是按C語言的標準處理串,是因為你會按C語言的標準構造串、而不是按其它的模式定義的。在我們的教材上,串相當與一個: struct ElemType {char *str; }; 構造的順序表、或者是…

Android之解決開啟熱點后跳轉頁面不穩定問題

1 問題 在Android8.0版本以后,開啟熱點我們采用的下面這種方式,但是跳轉頁面后熱點會斷開,手機不能互相傳文件了 權限說明:Android8.0需要位置權限和GPS權限,同時手機熱點還不能是開啟狀態。 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {try {mWifiManag…

linux如何獲取網卡計數信息,Linux下如何獲取網卡信息

有時候&#xff0c;寫程序的時候需要獲取計算機的網絡信息&#xff0c;比如IP地址、電腦名稱、DNS等信息。IP地址和電腦名稱是比較容易獲取到的&#xff0c;而要想獲取地址掩碼、DNS、網關等信息就有些麻煩了。在Windows下我們一般都是通過從注冊表讀取這些信息。在Linux怎么做…

Redis命令總結

1.用腳本批量刪除key redis-cli -h 127.0.0.1 keys "MAIN:GAME:GID:*" | xargs redis-cli -h 127.0.0.1 del轉載于:https://www.cnblogs.com/hiwen/p/4900968.html

可以只讀的 ServiceCollection

可以只讀的 ServiceCollectionIntro在 .NET 7 Preview 4 中&#xff0c;ServiceCollection 可以聲明為只讀了&#xff0c;這使得我們可以有效避免在構建了 ServiceProvider 之后再新增服務&#xff0c;導致服務注冊失敗。Sample在新的版本中&#xff0c;ServiceCollection 新增…

阿里云與中國聯通首個公共云平臺上線

11月8日&#xff0c;阿里云與中國聯通關于公共云合作的首個項目&#xff1a;浙江聯通“沃云Powered by Alibaba cloud” 平臺&#xff08;cloud.10010zj.com.cn&#xff09;正式發布上線。該平臺將以沃云品牌為客戶提供“阿里云聯通”服務&#xff0c;結合阿里云技術及浙江聯通…

IBM X System ServerGuide 8.41 服務器 系統安裝 引導盤

IBM X System ServerGuide 8.41 支持操作系統: 32位: Microsoft Windows 2003/2003 R2 (Enterprise, Standard, Web and DataCenter UV) Microsoft Small Business Server 2003/2003 R2 (Standard/Premium Edition) Microsoft Windows 2008 (Enterprise, Standard, Web and Dat…

Matlab R2018b簡體中文版完整安裝圖文教程(附安裝包下載)

目 錄 一、安裝過程 二、下載地址 matlab R2018b安裝包如下所示,包括主程序和補丁文件兩部分。 一、安裝過程 雙擊安裝包中的setup.exe。 選擇使用文件安裝MIYAO,點擊下一步。

Android之解決Android10.0通過熱點名字和密碼連接指定熱點網絡不能通信問題(2種解決辦法)

1 問題 Android10.0設備通過熱點名字和密碼連接另外一臺設置指定熱點,但是他們之間依然不能通信,網絡不可達。 Android10.0設備通過熱點名字和密碼連接另外一臺設置指定熱點,我用的是官方API,可以參考我的這篇博客 Android之通過用戶名和密碼連接指定wifi熱點(兼容Android…

《看聊天記錄都學不會C語言?太菜了吧》(20)(必懂!題解)我能知道2000年后的這個月一共有幾天

若是大一學子或者是真心想學習剛入門的小伙伴可以私聊我&#xff0c;若你是真心學習可以送你書籍&#xff0c;指導你學習&#xff0c;給予你目標方向的學習路線&#xff0c;無套路&#xff0c;博客為證。 本系列文章將會以通俗易懂的對話方式進行教學&#xff0c;對話中將涵蓋…

linux nginx線程池,nginx使用線程池提升9倍性能

眾所周知nginx使用異步&#xff0c;事件驅動方法處理連接。這意味著nginx使用一個worker進程處理多個連接和請求&#xff0c;而不是每一個請求有一個專門的進程或著線程處理(像傳統架構的服務器那樣&#xff0c;例如apache)。為了實現這個目的&#xff0c;nginx使用非阻塞模式的…

android 開源項目

https://github.com/Trinea/android-open-project http://a.codekk.com/轉載于:https://www.cnblogs.com/syjhsgcc/p/4902885.html

【空間數據庫】ArcSDE 10.7+SQLEXPRESS+ArcServer 10.7.ecp企業級數據庫環境搭建

作者一直使用的是ArcGIS10.6做空間數據庫相關工作,可以參照文章《ArcGIS 10.6 Database_Server_Desktop安裝、連接數據庫服務、創建企業級數據庫》。今天我們演示安裝ArcGIS10.7自帶的數據庫服務(SQL Server 2014 Express版本)、連接數據庫服務和創建數據庫。 一、軟件準備 …

Android之解決androidx.appcompat.widget.Toolbar去掉左邊距

1 問題 androidx.appcompat.widget.Toolbar默認左邊有間距 2 解決辦法 在Toolbar下面添加如下熟悉 app:contentInsetLeft"0dp"app:contentInsetStart"0dp"app:contentInsetEnd"0dp"app:maxButtonHeight"20dp"app:titleMargin"0…

C# 配置日志記錄

在 .NET Core 中&#xff0c;可以給配置文件使用提供程序&#xff0c;例如從 JSON 或 XML文件、環境變量或命令行參數中讀取配置。只需要從 NuGet 包 Microsoft.ExtensionsConfiguration 中創建一個ConfigurationBuilder&#xff0c;并向此構建器添加提供程序。要添加 JSON 提供…

使用“using” 的 “Cursor”

很多時候&#xff0c;我們會寫下面的這段代碼&#xff1a; private void button1_Click(object sender, EventArgs e) {Cursor cursor Cursor.Current;this.Cursor Cursors.WaitCursor;LongTimeMethod();this.Cursor cursor; }private void LongTimeMethod() {for (int i 0…

《看聊天記錄都學不會C語言?太菜了吧》(21)(必懂!題解)在現實生活中,打擂臺比賽爭名次竟用的是冒泡排序?

若是大一學子或者是真心想學習剛入門的小伙伴可以私聊我&#xff0c;若你是真心學習可以送你書籍&#xff0c;指導你學習&#xff0c;給予你目標方向的學習路線&#xff0c;無套路&#xff0c;博客為證。 本系列文章將會以通俗易懂的對話方式進行教學&#xff0c;對話中將涵蓋…