Extensions in UWP Community Toolkit - FrameworkElement Extensions

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

概述 UWP Community Toolkit Extensions 中有一個為FrameworkElement 提供的擴展 - FrameworkElement Extensions,本篇我們結合代碼詳細講解 FrameworkElement Extensions 的實現。 FrameworkE ...


概述

UWP Community Toolkit Extensions 中有一個為FrameworkElement 提供的擴展 - FrameworkElement Extensions,本篇我們結合代碼詳細講解 FrameworkElement Extensions 的實現。

FrameworkElement Extensions 為 FrameworkElement 提供了一種簡單的綁定實際尺寸的方式,擴展利用 EnableActualSizeBinding 來指定是否允許實時綁定實際尺寸中的 ActualWidth 和 ActualHeight。 接下來看看官方示例的截圖:

Source: https://github.com/Microsoft/UWPCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.UI/Extensions/FrameworkElement

Doc: https://docs.microsoft.com/zh-cn/windows/uwpcommunitytoolkit/extensions/frameworkelementextensions

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

 

開發過程

代碼分析

FrameworkElement Extensions 的功能實現比較簡單,在 FrameworkElementExtensions.cs 類中;先看一下類的結構:

我們看到,類中定義了三個依賴屬性:

  • EnableActualSizeBindingProperty - boolean,標誌是否允許實際尺寸綁定;屬性改變時觸發 OnEnableActualSizeBindingtPropertyChanged;
  • ActualHeightProperty - double,實際尺寸的高度; 預設值 double.NaN;
  • ActualWidthProperty - double,實際尺寸的寬度;預設值 double.NaN;

而這三個依賴屬性分別對應的 get 和 set 方法分別是:

  • GetEnableActualSizeBinding(obj) 和 SetEnableActualSizeBinding(obj, value) 
  • GetActualHeight(obj) 和 SetActualHeight(obj, value) 
  • GetActualWidth(obj) 和 SetActualWidth(obj, value) 

下麵看一下實際綁定和 EnableActualSizeBinding 的處理代碼:

 在 OnEnableActualSizeBindingtPropertyChanged(sender, args) 方法處理中,可以看到當 EnableActualSizeBinding 變為 True 時,強制刷新一次實際尺寸,且開始響應 SizeChanged 事件,處理同樣是刷新實際尺寸屬性;而當 EnableActualSizeBinding 變為 False 時,去掉 SizeChanged 事件的監聽;

這樣的結果就是,當 EnableActualSizeBinding 變為 False 時,獲取到的 ActualHeight 和 ActualWidrh 一直都是變為 False 時最後一個值,不管尺寸怎麼改變都不會被更新和監聽;

而通過擴展設置的綁定,和直接設置 ActualHeight 和 ActualWidth 的綁定的區別就是,直接設置的方式,對於 Width 和 Height 未指定的情況綁定無效,且不會更新,而擴展的方式可以獲取初始尺寸且可以實時更新;

private static void OnEnableActualSizeBindingtPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
    var baseElement = sender as FrameworkElement;
    if (baseElement == null)
    {
        return;
    }

    if ((bool)args.NewValue)
    {
        // Size may have changed while this was disabled, so we force an updated once user enables it
        UpdateActualSizeProperties(baseElement, null);

        // Subscribe to event
        baseElement.SizeChanged += UpdateActualSizeProperties;
    }
    else
    {
        // Unsubscribe from event
        baseElement.SizeChanged -= UpdateActualSizeProperties;
    }
}

在下麵的 UpdateActualSizeProperties(sender, args) 方法中,可以看到綁定目標的 ActualHeight 和 ActualWidth 在改變時,會實時賦值,這樣綁定的屬性就能得到實時的更新。

private static void UpdateActualSizeProperties(object sender, RoutedEventArgs routedEventArgs)
{
    var baseElement = sender as FrameworkElement;
    if (baseElement == null)
    {
        return;
    }

    // Update only if needed
    var currentHeight = GetActualHeight(baseElement);
    if (currentHeight != baseElement.ActualHeight)
    {
        SetActualHeight(baseElement, baseElement.ActualHeight);
    }

    // Update only if needed
    var currentWidth = GetActualWidth(baseElement);
    if (currentWidth != baseElement.ActualWidth)
    {
        SetActualWidth(baseElement, baseElement.ActualWidth);
    }
}

代碼簡單分析如上,大家在實際項目中可以對這個類進行擴展,比如把 Opacity,Color 等也作為可以實時綁定的值,實現方式和 ActualHeight ActualWidth 很類似,大家可以自行擴展,然後把擴展後的類提 PR 到 UWPCOmmunityToolkit Github 中。 

 

調用示例

我們創建了三個 Rectangle,第一個是綁定目標,第二和第三個去綁定第一個的實際尺寸;可以看到因為第二個紅色矩形使用 ActualHeight 和 ActualWidth 直接進行綁定,所以並沒有綁定到正確的值;而第三個淺藍色矩形的初始綁定值是正確的;而在第一個矩形的尺寸隨著 GridSplitter 變化時,紅色矩形沒有任何變化,而淺藍色矩形會跟隨變化更新尺寸;這和我們預期的結果是一致的。

<StackPanel x:Name="RootGrid" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Padding="48">
    <Grid Height="300">
        <Grid.RowDefinitions>
            <RowDefinition MinHeight="100" MaxHeight="300" />
            <RowDefinition Height="11" />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition MinWidth="100" MaxWidth="800" />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>

        <Rectangle Grid.Column="0" Grid.Row="0" extensions:FrameworkElementExtensions.EnableActualSizeBinding="True"
        Fill="Blue" Stroke="Gray" x:Name="TargetObject" StrokeThickness="1"/>

        <!--Column Grid Splitter-->
        <controls:GridSplitter Width="11" Background="Gray" GripperCursor="Default" HorizontalAlignment="Left" Grid.Column="1" 
                            ResizeDirection="Auto" ResizeBehavior="BasedOnAlignment" CursorBehavior="ChangeOnGripperHover" GripperForeground="White"/>

        <!--Row Grid Splitter-->
        <controls:GridSplitter Grid.Row="1" Background="Gray" Height="11" HorizontalAlignment="Stretch">
            <controls:GridSplitter.Element>
                <Grid>
                    <TextBlock HorizontalAlignment="Center" IsHitTestVisible="False" VerticalAlignment="Center" Text="&#xE76F;" 
                            Foreground="White" FontFamily="Segoe MDL2 Assets"/>
                </Grid>
            </controls:GridSplitter.Element>
        </controls:GridSplitter>
    </Grid>

    <Rectangle Margin="12,12" HorizontalAlignment="Left"
    Height="{Binding ElementName=TargetObject, Path=ActualHeight}"
    Width="{Binding ElementName=TargetObject, Path=ActualWidth}"
    Fill="Red" Stroke="Gray" StrokeThickness="1"/>

    <Rectangle Margin="12,12" HorizontalAlignment="Left"
    Height="{Binding ElementName=TargetObject, Path=(extensions:FrameworkElementExtensions.ActualHeight)}"
    Width="{Binding ElementName=TargetObject, Path=(extensions:FrameworkElementExtensions.ActualWidth)}"
    Fill="LightBlue" Stroke="Gray" StrokeThickness="1"/>
</StackPanel>

 

總結

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

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

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

 


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

-Advertisement-
Play Games
更多相關文章
  • 配置指令 (。。。) 錯誤日誌 (。。。) 異常處理 為什麼異常處理很方便 (。。。) PHP的異常處理實現 (。。。) SPL異常 (。。。) ...
  • 多態是C++的三大法器之一,此處我們用C模擬多態,加深對C++的多態的理解 ...
  • 聲明:以下轉載自:Java中的File文件類詳解 文件操作在Java的io操作中占有十分重要的地位,本文從以下幾個方面來接受Java中對文件的操作。 1.Java中新建或者刪除一個文件,文件夾以及createNewFile(),delete(),mkdir(),mkdirs()函數的使用。 2. 判 ...
  • using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks; namespace ConsoleApplication2{ class P ...
  • 註意:無論那種方法,都要先設置Tab控制項的Style屬性為fixed width.第一種方法MFC,tabcontrol控制項改變標簽大小 - CSDN博客 https://blog.csdn.net/u012702039/article/details/22668161CSize size, siz... ...
  • using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks; namespace ConsoleApplication1 { class ...
  • 用C#(.NET Core) 實現簡單工廠(簡單工廠不是設計模式)和工廠方法模式 ...
  • 問題描述 在很多系統中,存在多對多關係的維護。如下圖: 這種結構大部分有三個數據表,其中兩個具有主鍵的表,還有一個具有兩個鍵的關聯表,這個表中的兩個欄位既是主鍵又是外鍵。 如上圖,其中的Supplier表和Product是主業務表,ProductSupplier是關聯關係表,如果處理過一些複雜的業務... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...