New UWP Community Toolkit - DropShadowPanel

来源:https://www.cnblogs.com/shaomeng/archive/2018/04/06/8727884.html
-Advertisement-
Play Games

概述 UWP Community Toolkit 中有一個為 Frmework Element 提供投影效果的控制項 - DropShadowPanel,本篇我們結合代碼詳細講解 DropShadowPanel 的實現。 DropShadowPanel 提供的陰影效果有很多應用場景,比如給文本提供陰影 ...


概述

UWP Community Toolkit  中有一個為 Frmework Element 提供投影效果的控制項 - DropShadowPanel,本篇我們結合代碼詳細講解  DropShadowPanel 的實現。

DropShadowPanel 提供的陰影效果有很多應用場景,比如給文本提供陰影,可以讓文本在背景變化時可以明顯顯示,比如地圖上的標尺文本;應用在圖形或圖片時,可以設置陰影效果,另外它有很多參數可以調整,如陰影偏移,顏色,透明度和陰影模糊半徑等,14393 開始支持,下麵看看官方示例的截圖:

Source: https://github.com/Microsoft/UWPCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.UI.Controls/DropShadowPanel

Doc: https://docs.microsoft.com/zh-cn/windows/uwpcommunitytoolkit/controls/dropshadowpanel

Namespace: Microsoft.Toolkit.Uwp.UI.Controls; Nuget: Microsoft.Toolkit.Uwp.UI.Controls;

 

開發過程

代碼分析

我們先來看看 DropShadowPanel 控制項的類構成:

  • DropShadowPanel.Properties.cs - DropShadowPanel 控制項部分類的依賴屬性類
  • DropShadowPanel.cs - DropShadowPanel 控制項部分類的定義和處理方法
  • DropShadowPanel.xaml - DropShadowPanel 控制項的樣式文件

 

1. DropShadowPanel.Properties.cs

DropShadowPanel 控制項部分類的依賴屬性類,定義了以下依賴屬性:

  • Color - drop shadow 的顏色,變化時會觸發 OnColorChanged(d, e)
  • BlurRadius - drop shadow 的模糊半徑,變化時會觸發 OnBlurRadiusChanged(d, e)
  • OffsetX - drop shadow 的 x 軸方向偏移,變化時觸發 OnOffsetXChanged(d, e)
  • OffsetY - drop shadow 的 y 軸方向偏移,變化時觸發 OnOffsetYChanged(d, e)
  • OffsetZ - drop shadow 的 z 軸方向偏移,變化時觸發 OnOffsetZChanged(d, e)
  • ShadowOpacity - drop shadow 的陰影透明度,變化時觸發 OnShadowOpacityChanged(d, e)

2. DropShadowPanel.cs

DropShadowPanel 控制項的定義和處理邏輯,類繼承自 ContentControl;先來看看構造方法:

確定系統版本支持滿足條件後,創建一個 Compositor 和 dropShadow,創建 shadowVisual,並用 dropShadow 給它賦值;

public DropShadowPanel()
{
    this.DefaultStyleKey = typeof(DropShadowPanel);

    if (IsSupported)
    {
        Compositor compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;

        _shadowVisual = compositor.CreateSpriteVisual();

        _dropShadow = compositor.CreateDropShadow();
        _shadowVisual.Shadow = _dropShadow;
    }
}

接著來看一下上面 DropShadowPanel.Properties.cs 中屬性的變化觸發事件,實際的處理方法都在 DropShadowPanel.cs 類中,處理過程就是把 newValue 賦值給 dropShadow;

而在 OnSizeChanged(s, e) 事件觸發時,以及初始化時,主要處理邏輯是 UpdateShadowSize() 方法:

方法處理中,獲取需要設置投影的 Content,得到實際顯示寬度和高度,賦值給 shadowVisual;作為 dropShadow 的顯示宿主;

private void UpdateShadowSize()
{
    if (_shadowVisual != null)
    {
        Vector2 newSize = new Vector2(0, 0);
        if (Content is FrameworkElement contentFE)
        {
            newSize = new Vector2((float)contentFE.ActualWidth, (float)contentFE.ActualHeight);
        }

        _shadowVisual.Size = newSize;
    }
}

 更一個主要的處理方法是 UpdateShadowMask(),負責更新投影的 mask:

根據需要設置投影的 Content 類型,Image,Shape,TextBlock 或 ImageExBase,使用 GetAlphaMask() 來得到 alphaMask,賦值給 dropShadow 的 mask 屬性,作為投影效果的顯示效果;配合上面的 UpdateShadowSize() 方法,以及 Opacity,Offset 等屬性,正確顯示投影效果;

private void UpdateShadowMask()
{
    if (!IsSupported)
    {
        return;
    }

    if (Content != null)
    {
        CompositionBrush mask = null;

        if (Content is Image)
        {
            mask = ((Image)Content).GetAlphaMask();
        }
        else if (Content is Shape)
        {
            mask = ((Shape)Content).GetAlphaMask();
        }
        else if (Content is TextBlock)
        {
            mask = ((TextBlock)Content).GetAlphaMask();
        }
        else if (Content is ImageExBase imageExBase)
        {
            imageExBase.ImageExInitialized += ImageExInitialized;

            if (imageExBase.IsInitialized)
            {
                imageExBase.ImageExInitialized -= ImageExInitialized;

                mask = ((ImageExBase)Content).GetAlphaMask();
            }
        }

        _dropShadow.Mask = mask;
    }
    else
    {
        _dropShadow.Mask = null;
    }
}

3. DropShadowPanel.xaml

DropShadowPanel 控制項的樣式文件,我們來看 Template 部分:投影效果的實現,是使用一個 Border 放置在實際內容控制項的後面,通過 Border 中對內容的顯示和位置調整來實現投影。

<Style TargetType="controls:DropShadowPanel">
    <Setter Property="IsTabStop"
        Value="False" />
    <Setter Property="HorizontalAlignment" Value="Stretch"/>
    <Setter Property="HorizontalContentAlignment" Value="Left"/>
    <Setter Property="VerticalAlignment" Value="Stretch"/>
    <Setter Property="VerticalContentAlignment" Value="Stretch"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="controls:DropShadowPanel">
                <Grid Background="{TemplateBinding Background}"
                    BorderBrush="{TemplateBinding BorderBrush}"
                    BorderThickness="{TemplateBinding BorderThickness}"
                    HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
                    VerticalAlignment="{TemplateBinding VerticalAlignment}">
                    <Border x:Name="ShadowElement" 
                        HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                        VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
                    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                    VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

 

調用示例

下麵的示例中,我們定義了兩個相同的 TextBlock,其中一個應用了 DropShadow,一個未應用,可以看出,應用了 DropShadow 的一個,文本明顯會有模糊的黑色陰影;

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <StackPanel Orientation="Vertical" VerticalAlignment="Center">
<controls:DropShadowPanel BlurRadius="10" ShadowOpacity="0.8"
                                OffsetX="0" OffsetY="0" Color="Black"
                                VerticalAlignment="Center" HorizontalAlignment="Center">
            <TextBlock FontSize="20"  TextWrapping="Wrap">
        The DropShadowPanel Control allows the creation of a drop shadow effect for any Xaml FrameworkElement in the markup. 
        You can control the following property of the drop shadow effect : Offset, Color, Opactity and Blur Radius.
        NOTE: Windows Anniversary Update (10.0.14393.0) is needed to support correctly this effect.
    </TextBlock>
    </controls:DropShadowPanel>
        <TextBlock TextWrapping="Wrap" FontSize="20" Margin="0,10,0,0">
        The DropShadowPanel Control allows the creation of a drop shadow effect for any Xaml FrameworkElement in the markup. 
        You can control the following property of the drop shadow effect : Offset, Color, Opactity and Blur Radius.
        NOTE: Windows Anniversary Update (10.0.14393.0) is needed to support correctly this effect.
        </TextBlock>
    </StackPanel>
</Grid>

 

總結

到這裡我們就把 UWP Community Toolkit 中的 DropShadowPanel 控制項的源代碼實現過程和簡單的調用示例講解完成了,希望能對大家更好的理解和使用這個控制項有所幫助。歡迎大家多多交流,謝謝!

最後,再跟大家安利一下 UWPCommunityToolkit 的官方微博:https://weibo.com/u/6506046490大家可以通過微博關註最新動態。

衷心感謝 UWPCommunityToolkit 的作者們傑出的工作,Thank you so much, UWPCommunityToolkit authors!!!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 持久化就是將記憶體中的數據保存起來,使之可以長期存在。 在Java中 可以做到持久化有很多種方法。 其中有: 1. 堵塞型IO,也就是我們經常說的io流; 2. 非堵塞型IO,通常稱為New IO。也就是我們經常說的nio 3. Xml 4. 序列化 5. 資料庫持久化 本人將在之後博客中開展關於Ja ...
  • 一、概述 很多程式都有記錄日誌的需求,並且日誌中包含的信息即有正常的程式訪問日誌,還可能有錯誤、警告等信息輸出,python的logging模塊提供了標準的日誌介面,你可以通過它存儲各種格式的日誌,logging的日誌可以分為 debug(), info(), warning(), error()  ...
  • Python的數據類型在前幾節我們都簡單的一一介紹了,接下來我們就要講到Python的控制判斷迴圈語句 在現實編程中,我們往往要利用電腦幫我們做大量重覆計算的工作,在這樣的情況下,需要機器能對某個條件進行判斷,或是對某個行為進行重覆操作 這時我們就必須要知道如何去編寫迴圈判斷語句 if... el ...
  • 1.安裝anaconda 下載地址:[清華鏡像站][url1] 針對自己的操作系統,在 下載鏈接 應用軟體 conda 中選擇合適版本。安裝過程較為簡單,這裡就不在詳細介紹。 需要註意 的是windows系統安裝過程中需要註意,勾選將軟體添加至windows路徑(也可以手動添加,即在環境變數 pat ...
  • 在項目中,遇到需求,需要進行規則入庫,想到使用正則進行表達式的拆分和分類,具體如下: 目標是:拆分介於表示邏輯運算的“And”或者“Or”的子句,比如:Operation Mode(Operation Mode_2) (Approve CR1) equals Accept;Need Physical ...
  • 題目描述 給定一個完全圖,保證$w_{u,v}=w_{v,u}$且$w_{u,u}=0$,等概率選取一個隨機生成樹,對於每一對$(u,v)$,求$dis(u,v)$的期望值對$998244353$取模。 輸入 第一行一個數$n$ 接下來$n$行,每行$n$個整數,第$i$行第$j$個整數表示$w_{ ...
  • 因為對錶達式樹有點興趣,出於練手的目的,試著寫了一個深拷貝的工具庫。支持.net standard2.0或.net framework4.5及以上。 GitHub地址https://github.com/blurhkh/DeepCopier nuget地址https://www.nuget.org/ ...
  • 一、WebApi路由機制是什麼? 路由機制通俗點來說:其實就是WebApi框架將用戶在瀏覽器中輸入的Url地址和路由表中的路由進行匹配,並根據最終匹配的路由去尋找並匹配相應的Controller和Action並執行的一個過程。 從WebApi框架接收到來自外部環境的介面調用請求到指定介面的執行大概需 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...