WPF|快速添加新手引導功能(支持MVVM)

閱讀導航

  1. 前言

  • 案例一

  • 案例二

  • 案例三(本文介紹的方式)

  1. 如何使用?

  2. 控件如何開發的?

  3. 總結

1. 前言

案例一

站長分享過 眾尋 大佬的一篇 WPF 簡易新手引導 一文,新手引導的效果挺不錯的,如下圖:

7f2bf0c7fad2882be9b6c22ec04fd226.gif

該文給出的代碼未使用 MVVM 的開發方式,提示框使用的用戶控件、蒙版窗體樣式與后臺代碼未分離,但給大家分享了開發新手引導功能的一個參考。

案例二

開源項目 AIStudio.Wpf.Controls,它的新手引導效果如下:

346c8ecbe821798660bc5c3fb8879ca5.gif

此開源項目也有參考上文(WPF 簡易新手引導),并且重構為 MVVM 版本,方便綁定使用。

并且提示框顯示的位置還跟隨目標控件在主窗體中的位置靈活變換,不至于顯示在蒙版窗體之外,如下圖所示:

當目標控件右側空間足夠顯示引導提示框時,引導提示框就顯示在目標控件右側;在右側空間不足時,則將引導提示框顯示在目標控件左側:

124a795810468a2cd86c5f9bf17d270d.png

案例三(本文介紹的方式)

站長根據上面的開源項目 AIStudio.Wpf.Controls 做了一個自己的版本 Dotnet9WPFControls,去掉了上一步按鈕、增加標題綁定、下一步按鈕內容綁定、提示框樣式修改等,效果如下:

42861cc355c6c870922a371b5945ac18.gif

后面段落就介紹 怎么使用 Dotnet9WPFControls 添加新手引導功能,并簡單提及這個自定義控件的開發細節,主要原理還是看上文 WPF 簡易新手引導 哈。

希望對有需要給自己的項目添加新手引導功能的朋友有一定幫助,通過此文你也能修改出滿足自己需求的效果。

2. 如何使用?

2.1 創建一個WPF項目

使用 .NET 6|7 創建一個名為 "NewbieGuideDemo" 的 WPF 解決方案:

37afba082f9951a9b05eefafb478b826.png

2.2 引入nuget包

  • 添加Nuget包1:Dotnet9WPFControls

該包提供引導控件及其樣式,記得勾選“包括預發行版”,然后點擊安裝。

6c8db172262fc2b170ffd32ceb7ae6ae.png
  • 添加Nuget包2:Prism.DryIoc

使用該包,主要是使用 Prism 封裝的一些 MVVM、IOC 功能,方便協助開發。

添加上述兩個Nuget包后,項目工程文件定義如下:

<Project?Sdk="Microsoft.NET.Sdk"><PropertyGroup><OutputType>WinExe</OutputType><TargetFramework>net6.0-windows</TargetFramework><Nullable>enable</Nullable><UseWPF>true</UseWPF></PropertyGroup><ItemGroup><PackageReference?Include="Dotnet9WPFControls"?Version="0.1.0-preview.2"?/><PackageReference?Include="Prism.DryIoc"?Version="8.1.97"?/></ItemGroup></Project>

2.3 添加樣式文件

打開 App.xaml 文件,引入 Dotnet9WPFControls 默認主題文件:

<prism:PrismApplicationx:Class="NewbieGuideDemo.App"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:prism="http://prismlibrary.com/"><prism:PrismApplication.Resources><ResourceDictionary><ResourceDictionary.MergedDictionaries><ResourceDictionary?Source="pack://application:,,,/Dotnet9WPFControls;component/Themes/Dotnet9WPFControls.xaml"?/></ResourceDictionary.MergedDictionaries></ResourceDictionary></prism:PrismApplication.Resources>
</prism:PrismApplication>

注意上面的根節點 <prism:PrismApplication />,同時修改App.xaml.cs文件,這里不做過多說明,具體使用請參考 Prism:

using?Prism.DryIoc;
using?Prism.Ioc;
using?System.Windows;namespace?NewbieGuideDemo
{public?partial?class?App?:?PrismApplication{protected?override?void?RegisterTypes(IContainerRegistry?containerRegistry){}protected?override?Window?CreateShell(){return?Container.Resolve<MainWindow>();}}
}

2.4 定義引導信息

給主窗體 MainWindow 添加一個 ViewModel 類:MainWindowViewModel.cs

using?Dotnet9WPFControls.Controls;
using?Prism.Mvvm;
using?System.Collections.Generic;namespace?NewbieGuideDemo
{public?class?MainWindowViewModel?:?BindableBase{private?GuideInfo??_guide;public?GuideInfo?Guide?=>_guide???=?new?GuideInfo("快速添加新手引導",?"這樣添加新手引導,或許比較優雅");public?List<GuideInfo>?Guides?=>?new()?{Guide};}
}

在上面的 ViewModel 中,定義了一個引導屬性 Guide,這個屬性是與提示框綁定展示:

50903a187cb12829d6d6ef996558d58a.png
  • 第一個參數定義了引導提示框的標題 “快速添加新手引導”

  • 第二個參數定義了引導提示框的提示內容 “這樣添加新手引導,或許比較優雅”

第二個屬性 Guides, 是一個引導信息列表,可綁定多個引導信息,點擊按鈕即會查看下一個引導,本示例為了演示,只寫了一個引導。

2.5 界面綁定引導信息

先貼上 MainWindow.xaml 所有代碼:

<Windowx:Class="NewbieGuideDemo.MainWindow"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:prism="http://prismlibrary.com/"xmlns:i="http://schemas.microsoft.com/xaml/behaviors"xmlns:dotnet9="https://dotnet9.com"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"Title="Dotnet9?WPF新手引導功能"?Width="800"?Height="450"prism:ViewModelLocator.AutoWireViewModel="True"AllowsTransparency="True"?Background="Transparent"?WindowStyle="None"?WindowStartupLocation="CenterScreen"mc:Ignorable="d"><Window.Resources><dotnet9:BindControlToGuideConverter?x:Key="BindControlToGuideConverter"?/></Window.Resources><BorderBackground="White"?BorderBrush="#ccc"?BorderThickness="1"?MouseLeftButtonDown="Border_MouseDown"><Grid><Button?HorizontalAlignment="Center"?VerticalAlignment="Center"?Content="點擊測試新手引導"><dotnet9:GuideHelper.GuideInfo><MultiBinding?Converter="{StaticResource?BindControlToGuideConverter}"><Binding?RelativeSource="{RelativeSource?Self}"?/><Binding?Path="Guide"?/></MultiBinding></dotnet9:GuideHelper.GuideInfo><i:Interaction.Triggers><i:EventTrigger?EventName="Click"><i:ChangePropertyAction?PropertyName="Display"?TargetName="GuideControl"?Value="True"?/></i:EventTrigger></i:Interaction.Triggers></Button><dotnet9:GuideControl?x:Name="GuideControl"?Guides="{Binding?Guides}"><i:Interaction.Triggers><i:EventTrigger?EventName="Loaded"><i:ChangePropertyAction?PropertyName="Display"?Value="True"?/></i:EventTrigger></i:Interaction.Triggers></dotnet9:GuideControl></Grid></Border>
</Window>

下面快速過一遍。

2.5.1 引入的命名空間說明

看上面的代碼,引入了 dotnet9prismi三個命名空間:

  • dotnet9 命名空間

引入引導控件 GuideControl 及 轉換器 BindControlToGuideConverter

  • prism 命名空間

主要用途在 prism:ViewModelLocator.AutoWireViewModel="True" 這句代碼,將視圖 MainWindow.xamlMainWindowViewModel.cs進行綁定,有興趣可以看 Prism 源碼,了解視圖是如何發現ViewModel的約定規則。

  • i 命名空間

主要用此命名空間下的觸發器,事件觸發屬性更改。

2.5.2 幾處關鍵代碼簡單說明

上面代碼貼的是引導控件(自定義控件)的使用方式(站長注:Dotnet9WPFControls 中還有引導窗體的方式,本文不做說明,要不然太占篇幅了,請查看控件Demo GuideWindowView)。

a: 將引導控件加到容器最上層

先關注后面的幾行代碼:

<Grid><!--這里省略業務控件布局--><dotnet9:GuideControl?x:Name="GuideControl"?Guides="{Binding?Guides}"><i:Interaction.Triggers><i:EventTrigger?EventName="Loaded"><i:ChangePropertyAction?PropertyName="Display"?Value="True"?/></i:EventTrigger></i:Interaction.Triggers></dotnet9:GuideControl>
</Grid>
  • 將引導控件加到 Grid 容器最后,意圖是讓引導控件顯示在所有控件的最上層(同一層級添加了多個控件,如果位置重疊,那么后加入的控件會顯示在先添加的控件上方,呈現遮擋效果);

  • 綁定了前面 MainWindowViewModel 中定義的引導信息列表 Guides,點擊下一步按鈕(本文顯示為我知道了)時,會按列表添加順序切換引導信息;

  • 使用 i:Interaction.Triggers實現控件加載完成時,自動顯示引導提示信息,見上面的 示例三效果;

b:綁定目標控件與引導屬性

目標控件的引導屬性與目標控件引用綁定,引導界面顯示時通過目標控件計算出目標控件的位置和大小,準確將目標控件標識出來,引導提示框定位也才能正確設置:

<dotnet9:BindControlToGuideConverter?x:Key="BindControlToGuideConverter"?/>
<Button?HorizontalAlignment="Center"?VerticalAlignment="Center"?Content="點擊測試新手引導"><dotnet9:GuideHelper.GuideInfo><MultiBinding?Converter="{StaticResource?BindControlToGuideConverter}"><Binding?RelativeSource="{RelativeSource?Self}"?/><Binding?Path="Guide"?/></MultiBinding></dotnet9:GuideHelper.GuideInfo><i:Interaction.Triggers><i:EventTrigger?EventName="Click"><i:ChangePropertyAction?PropertyName="Display"?TargetName="GuideControl"?Value="True"?/></i:EventTrigger></i:Interaction.Triggers>
</Button>

如上代碼引入 BindControlToGuideConverter 轉換器, 該轉換器是個黏合類,將目標控件的引用添加到引導對象上,轉換器具體定義如下:

public?class?BindControlToGuideConverter?:?IMultiValueConverter
{public?object??Convert(object[]?values,?Type?targetType,?object?parameter,?CultureInfo?culture){if?(values.Length?<?2){return?null;}var?element?=?values[0]?as?FrameworkElement;var?guide?=?values[1]?as?GuideInfo;if?(guide?!=?null){guide.TargetControl?=?element;}return?guide;}public?object[]?ConvertBack(object?value,?Type[]?targetTypes,?object?parameter,?CultureInfo?culture){throw?new?NotImplementedException();}
}

目標控件的引用賦值給引導對象的 TargetControl 屬性。

Demo代碼完畢,直接運行項目,效果如下,源碼在這 NewbieGuideDemo:

1fd3122e71818ed14b79547ab4b6b3a6.gif

3. 控件如何開發的?

關于原理,WPF 簡易新手引導 這篇介紹的不錯,可以先看看。

關于本示例的實現方式,暫時不做太多說明,詳細請直接查看源碼 Dotnet9WPFControls,本文后半截大概提一下。

代碼組織結構如下:

57ecb2edba52a2b485511a726c0cdf3d.png
  • GuideInfo:定義引導信息類,如標題、內容、下一步按鈕顯示內容。

  • GuideHintControl:引導提示框控件,顯示引導標題、引導內容、下一步按鈕,即 GuideInfo 綁定的控件。

  • GuideControl:引導控件,用于目標控件無法獲取到自己的窗體這種(即無法獲取在窗體中的位置),比如您開發的程序為第三方程序插件這種,上面的代碼即是使用此引導控件實現的效果。

  • GuideWindow:引導窗體,GuideControl 引導控件的相互補充。

  • GuideControlBase:引導控件輔助類

  • BindControlToGuideConverter:引導信息與引導的目標控件綁定轉換器

  • GuideHelper:引導幫助類,綁定目標控件的引導信息使用,外加一個顯示 引導窗體 的靜態命令。

  • Guide.xaml:定義引導遮罩層(GuideControlGuideWindow)、引導提示框(GuideHintControl)樣式的資源文件,定義外觀請改這個文件

重點:

a) GuideControlBase

GuideControlBaseGuideControlGuideWindow 的輔助類,因為這兩個類實現的功能是類似的,所以封裝大部分功能在 GuideControlBase 中,比如將目標控件區域從遮罩層 Clip 出來,并將 GuideHintControl 提示框控件添加到遮罩層之上,顯示出新手引導的效果。

b) GuideControl 和 GuideWindow

GuideControl 是用于顯示在包含目標控件的容器內使用的,GuideControl放置的容器不一定是目標控件的直接容器,可以有嵌套,比如目標控件在ListBox子項ListBoxItem內,而引導控件GuideControl可以在ListBox的外層容器之上;

GuideWindow 用于貼在目標控件所在的窗體上,GuideWindow 作為目標控件窗體的子窗體,Show()在目標控件窗體上,不能使用ShowDialog()的方式(為啥?ShowDialog()會使除引導窗體之外的窗體處于無效狀態(disable))。

這兩種方式(GuideControl 和 GuideWindow)總體呈現效果是一樣的,目標控件所在的窗體是自定義窗體,Demo能正常顯示下面的效果,普通窗體需要對目標控件 Clip 的位置和提示框的位置進行偏移處理,修改位置見 GuideControlGuideWindow的方法 ShowGuide(FrameworkElement? targetControl, GuideInfo guide)

控件帶的兩個新手引導Demo如下:

新手引導Demo一

GuideControl方式,站長推薦,即以控件的方式顯示新手引導,點擊看代碼:

5dcbb00372503c281e321f01f8eac905.gif

新手引導Demo二

GuideWindow方式,即以子窗體的方式顯示新手引導,點擊看代碼:

0c6df124097548f3a56d67c5984cb4d2.gif

詳細開發不展開說了,一切都在代碼中。

4. 總結

前面寫了不少,其實不多,謝謝開源帶來的力量。

  • 參考文章:WPF 簡易新手引導

  • 參考開源項目:AIStudio.Wpf.Controls

  • 本文Demo NewbieGuideDemo:Github、Gitee

  • Dotnet9Controls 新手引導Demo一 源碼:Github、Gitee

  • Dotnet9Controls 新手引導Demo二 源碼 GuideWindowView:Github、Gitee

  • Dotnet9Controls控件:Github、Gitee

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

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

相關文章

三、界面介紹(IVX快速手冊)

三、集成開發環境界面介紹 通過本節你將了解 iVX 在線集成開發環境 界面&#xff0c;快速建立對 在線集成開發環境 的認識。 文章目錄三、集成開發環境界面介紹3.1 界面區域3.2 舞臺3.3 組件工具欄3.4 對象樹/素材面板3.5 屬性面板3.6 菜單面板3.7 邏輯工具面板3.8 輔助工具3.…

Android studio之提示Failed to resolve: com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.46

1、錯誤提示如下 Failed to resolve: com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.46 Show in Project Structure dialog Affected Modules: app2、解決辦法 在project的build.gradle里面加入 maven { url https://jitpack.io }

【VB測繪程序設計】第二章 VB測繪程序基礎

第一節 數據類型 VB中提供了以下11中基本的數據類型: 一、數值型 二、字符串 三、日期型 1.界面設計 2. 代碼 <

React-引領未來的用戶界面開發框架-讀書筆記(六)

第12章 服務端渲染 想讓搜索引擎抓取到你的站點&#xff0c;服務端渲染這一步不可或缺&#xff0c;服務端渲染還可以提升站點的性能&#xff0c;因為在加載JavaScript腳本的同時&#xff0c;瀏覽器就可以進行頁面渲染。 React的虛擬DOM是其可被用于服務端渲染的關鍵。首先每個R…

TrimPath - Js模板引擎

當頁面中引用template.js文件之后&#xff0c;腳本將創建一個TrimPath對象供你使用。 parseDOMTemplate(elementId,optionalDocument)  //獲得模板字符串代碼 得到頁面中Id為elementId的DOM組件的InnerHTML&#xff0c;將其解析成一個模板&#xff0c;這個返回一個templateOb…

appserv安裝

Appserv 官網: http://www.appservnetwork.com/ 安裝好后&#xff0c;輸入http://localhost:8082/驗證是否裝成功&#xff0c;成功后如下圖 http://localhost:8082/ 默認指定的文件夾是 進入到phpMyAdmin 的賬號是root&#xff0c;密碼是安裝時的密碼

一、iVX簡介(IVX 快速開發教程)

一、iVX簡介 通過本節你將對 iVX 有一個大致的認識&#xff0c;并且了解 iVX 能夠做些什么&#xff0c;有哪一些優勢&#xff0c;這將幫助你更好的上手 iVX 進行應用的開發&#xff0c;初步了解 iVX 的強大之處。 文章目錄一、iVX簡介1.1 iVX 是什么&#xff1f;1.2 iVX適合怎…

WPF效果第一百八十六篇之又玩ListBox

大周末的接著上一篇玩耍TreeView,這二天又再次去玩耍ListBox;畢竟是我的最愛,沒辦法就喜歡玩耍他;閑話也不多扯了,直接看咱們最終效果:2、原來一直ItemTemplate,這次直接ListBoxItem的Template:<Setter Property"Template"><Setter.Value><ControlTem…

Android之URL “page={page}category_id={***} string For dynamic query parameters use @Query.

1、問題 我們用retrofit進行Get網絡請求的時候&#xff0c;我代碼是這樣寫的 GET("/api/get_****/***?page{page}&category_id{category_id}")suspend fun getWebsiteCategory(Path("page") page: Int, Path("category_id") category_id: …

【VB測繪程序設計】第三章 VB結構化程序設計(順序、選擇、循環)

目 錄 第一節 順序結構設計 第二節 選擇結構設計 第三節 循環結構設計 第一節 順序結構設計 一、賦值語句

React-引領未來的用戶界面開發框架-讀書筆記(七)

第14章 開發工具 React使用了若干的抽象層來幫助你更輕松地開發組件、推導程序狀態。然而&#xff0c;在調試、構建及分發應用時&#xff0c;這樣設計就會產生負面影響了。 幸運的是&#xff0c;我們擁有一些非常好的開發工具能在開發及構建過程中為我們提供幫助。在這里探討這…

【十分鐘】學會微信小游戲,攀登不止小游戲制作(IVX 快速開發教程十一)

十一、攀登不止小游戲制作 制作微信小游戲大致流程與微信小程序、Web類似&#xff0c;不同的在于是組件的使用。我們此節需要完成的小游戲需求為&#xff1a; 小球觸碰矩形塊會跳躍或攀爬小球觸碰頂部或底部游戲結束點擊屏幕將會使小球朝著該方向移動小球進行跳躍時分數會增加…

十天沖刺---Day8

站立式會議 站立式會議內容總結&#xff1a;燃盡圖照片最近思考一個問題。項目是怎么進行到這一步的。算了&#xff0c;這個發在明天的沖刺總結吧。。還需繼續努力&#xff0c;隊友快回來快回來。。轉載于:https://www.cnblogs.com/imguang/p/4965054.html

Android之去掉RecycleView和NestedScrollView邊緣效果

1 問題 使用RecycleView和NestedScrollView的時候&#xff0c;滑倒頂部或者底部&#xff0c;會有邊緣效果&#xff0c;就像水溫波一樣&#xff0c;現在需求去掉 2 解決辦法 在RecycleView和NestedScrollView的xml文件里面加上如下屬性即可。 android:overScrollMode"nev…

Action過濾器重構

&#xff08;注&#xff1a;本文參照 NickChapsas的Attributes get a feature long-overdue in C# 11&#xff09;今天看一個泛型特性的例子&#xff0c;這個功能在C#11才受支持。在asp.net core mvc中&#xff0c;可以給action添加filter&#xff0c;達到攔截作用&#xff0c;…

征集對Oracle的問題

兩月前收到Oracle的邀請&#xff0c;10.10-16日參加在舊金山舉辦Oracle Open World 2009&#xff0c;旅程連上了長假。很榮幸&#xff0c;我是中國惟一入選的博客&#xff08;感謝小松and北北&#xff0c;還有小廢物同學經年累月的鞭策和誘導&#xff0c;北北同學的誘導尤其受用…

一篇文學會商用可編輯問卷表單制作【iVX 十二】

公共表單 在 iVX 快速教程中&#xff0c;我們使用一個公共表單項目作為 WebApp 應用的演示說明。公共表單項目可以用于企業內部或一個問卷公共平臺做問卷調查&#xff0c;用戶可以自由的設置表單元素以及樣式&#xff0c;并且可以手動設置表單結束下載填寫問卷后的調查數據。 …

【地圖學】地圖投影的定義和分類

一、地圖投影 1、地圖投影的定義 地圖投影是利用一定數學法則把地球表面的經、緯線轉換到平面上的理論和方法。 2、地圖投影的分類 (1)按變形性質 ? 等角投影: 投影面上兩微分線段的夾角與地面上的相應兩線段的夾角相等,及沒有角度變形的投影叫 ~ 。

React-引領未來的用戶界面開發框架-讀書筆記(八)

第16章 架構模式 React主要功能在于渲染HTML。可以將其看成是MVC中的V&#xff0c;它不會影響到組件中直接調用AJAX請求之類的操作&#xff1a; var TakeSurveyReact.CreateClass({getInitialData&#xff1a;function(){return{survey:null}&#xff1b;},componentDidMount:…

三)mybatis 二級緩存,整合ehcache

mybatis-config.xml <setting name"cacheEnabled" value"true" /> PersonMapper.xml <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http:…